Skip to content
This repository has been archived by the owner on Jun 29, 2020. It is now read-only.

Use of headless JRE causes problems #15

Closed
hho opened this issue Aug 20, 2015 · 13 comments
Closed

Use of headless JRE causes problems #15

hho opened this issue Aug 20, 2015 · 13 comments

Comments

@hho
Copy link

hho commented Aug 20, 2015

When a webapp tries to render text (for example, while generating a chart with JFreeChart, PDFs etc.), a NPE is thrown:

java.lang.NullPointerException
    at sun.awt.FontConfiguration.getVersion(FontConfiguration.java:1264)
    at sun.awt.FontConfiguration.readFontConfigFile(FontConfiguration.java:219)
    at sun.awt.FontConfiguration.init(FontConfiguration.java:107)
    at sun.awt.X11FontManager.createFontConfiguration(X11FontManager.java:776)
    at sun.font.SunFontManager$2.run(SunFontManager.java:431)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.font.SunFontManager.<init>(SunFontManager.java:376)
    at sun.awt.X11FontManager.<init>(X11FontManager.java:57)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
    at java.lang.Class.newInstance(Class.java:442)
    at sun.font.FontManagerFactory$1.run(FontManagerFactory.java:83)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.font.FontManagerFactory.getInstance(FontManagerFactory.java:74)
    at sun.font.SunFontManager.getInstance(SunFontManager.java:250)
    at sun.font.FontDesignMetrics.getMetrics(FontDesignMetrics.java:264)
    at sun.java2d.SunGraphics2D.getFontMetrics(SunGraphics2D.java:855)
    at org.jfree.text.G2TextMeasurer.getStringWidth(G2TextMeasurer.java:79)
    at org.jfree.text.TextUtilities.nextLineBreak(TextUtilities.java:306)
    at org.jfree.text.TextUtilities.createTextBlock(TextUtilities.java:247)
    at org.jfree.chart.title.TextTitle.arrangeRR(TextTitle.java:628)
    at org.jfree.chart.title.TextTitle.arrange(TextTitle.java:496)
    at org.jfree.chart.JFreeChart.drawTitle(JFreeChart.java:1311)
    at org.jfree.chart.JFreeChart.draw(JFreeChart.java:1203)
    at org.jfree.chart.JFreeChart.createBufferedImage(JFreeChart.java:1399)
    at org.jfree.chart.JFreeChart.createBufferedImage(JFreeChart.java:1379)
    at org.jfree.chart.ChartUtilities.writeChartAsPNG(ChartUtilities.java:184)
    at org.jfree.chart.ChartUtilities.writeChartAsPNG(ChartUtilities.java:138)
    at my.awttest.AwtTestServlet.renderChart(AwtTestServlet.java:49)
    at my.awttest.AwtTestServlet.doGet(AwtTestServlet.java:28)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:816)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:583)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
    at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548)
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:226)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1114)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:511)
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1048)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
    at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:213)
    at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:109)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:119)
    at org.eclipse.jetty.server.Server.handle(Server.java:517)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:302)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:242)
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:245)
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:95)
    at org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:75)
    at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceAndRun(ExecuteProduceConsume.java:213)
    at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:147)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:654)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:572)
    at java.lang.Thread.run(Thread.java:745)

This happens because the underlying JRE is the openjdk-8-jre-headless Debian package. The exception goes away when I add the fontconfig package to the image. [1]

I'd also suggest to set the default JAVA_OPTIONS to -Djava.awt.headless=true instead of leaving it blank. While that's not strictly necessary, it probably makes sense to tell any running app not to create dialogs etc. [2]

@md5
Copy link
Member

md5 commented Aug 20, 2015

Thanks for your report. There has been some previous discussion of this issue here: docker-library/openjdk#46

I'm curious whether setting JAVA_OPTIONS=-Djava.awt.headless=true actually fixed anything in your testing. I wouldn't think it would, since JFreeChart is still going to try to render fonts even if that's set.

@hho
Copy link
Author

hho commented Aug 20, 2015

Nope, setting that property didn't change anything for that particular problem. It just feels "more correct" that way; and maybe other libraries are smarter than JFreeChart?

I've pushed my test web app: https://github.com/hho/awttest

@md5
Copy link
Member

md5 commented Aug 20, 2015

I can't see how JFreeChart can draw a chart without using the java.awt.Font APIs. It's fundamental to what the library does, so it's not a matter of whether it's smart or not.

@md5
Copy link
Member

md5 commented Aug 20, 2015

FWIW, I've asked the maintainers of the java image about putting in a temporary fix.

I don't think we shoud add libfontconfig1 to the jetty image directly since this is a more general problem.

@hho
Copy link
Author

hho commented Aug 20, 2015

Yeah, this is probably better handled in the java image there. I'm closing this.

@hho hho closed this as completed Aug 20, 2015
@md5
Copy link
Member

md5 commented Aug 20, 2015

👍

@md5
Copy link
Member

md5 commented Aug 20, 2015

@hho This has been fixed in the java image, though the updated builds haven't been updated in docker-library/official-images yet and thus haven't been pushed. When they do, a rebuild of jetty should take place as well. 👍

@hho
Copy link
Author

hho commented Aug 20, 2015

Thanks! Your turnaround time on this one is amazing!! 👍 👍 👍

@md5
Copy link
Member

md5 commented Aug 20, 2015

Well, it certainly helps that we discussed it almost a month ago 🤘

@hho
Copy link
Author

hho commented Aug 21, 2015

The Java image has been pushed and I can confirm that your Dockerfile now results in Jetty image which works with java.awt. Thanks again!

@md5
Copy link
Member

md5 commented Aug 24, 2015

No problem @hho. Thanks for confirming the fix.

@tlvenn
Copy link

tlvenn commented Nov 7, 2016

While the default image is indeed fixed, the alpine based image is not however :(

@md5
Copy link
Member

md5 commented Nov 11, 2016

@tlvenn See docker-library/openjdk#73 where we discussed a workaround.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants