Description
While trying to generate a native image from a simple sample using the java.awt.Font class, I've noticed that the java.home variable is not set.
Since native-image aims at creating self contained executables which run independently of any available JRE, this is expected behavior.
However, some Java classes require it to load resources from the respective location.
In my case, the use fonts triggers a font configuration file to be loaded, which terminates with the following exception:
Exception in thread "main" java.lang.Error: java.home property not set
at sun.awt.FontConfiguration.findFontConfigFile(FontConfiguration.java:182)
at sun.awt.FontConfiguration.<init>(FontConfiguration.java:99)
at sun.awt.motif.MFontConfiguration.<init>(MFontConfiguration.java:48)
at sun.awt.X11FontManager.createFontConfiguration(X11FontManager.java:762)
at sun.font.SunFontManager$2.run(SunFontManager.java:431)
at java.security.AccessController.doPrivileged(AccessController.java:69)
at sun.font.SunFontManager.<init>(SunFontManager.java:376)
at sun.awt.FcFontManager.<init>(FcFontManager.java:35)
at sun.awt.X11FontManager.<init>(X11FontManager.java:57)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at java.lang.Class.newInstance(DynamicHub.java:778)
at sun.font.FontManagerFactory$1.run(FontManagerFactory.java:83)
at java.security.AccessController.doPrivileged(AccessController.java:69)
at sun.font.FontManagerFactory.getInstance(FontManagerFactory.java:74)
at java.awt.Font.getFont2D(Font.java:491)
at java.awt.Font.getFamily(Font.java:1220)
at java.awt.Font.getFamily_NoClientCode(Font.java:1194)
at java.awt.Font.getFamily(Font.java:1186)
at java.awt.Font.toString(Font.java:1683)
at java.lang.String.valueOf(String.java:2994)
at java.io.PrintStream.println(PrintStream.java:821)
at GraalTest.main(GraalTest.java:10)
Setting the variable at runtime works, but means that the image either requires an installed JRE or needs to be bundled with the respective resources from the JRE manually.
Even if this is pretty easy to work around, I think it might be worth providing a standardised or automated way to bundle JRE resources, especially since JRE provided classes should work with as litte manual tinkering as possible.
This could be done by adding an additional configuration file, like the ones that allow reflection or JNI access. Using this file, a directory containing all required JRE resources could be created alongside the native image and JAVA_HOME could be pointed there.
As I am not entirely sure how many cases would profit from this and how often resources are loaded from JAVA_HOME, an approach like this might be overly complex. As an alternative, providing premade archives that contain all of the respective resources might yield similar results without any major tradeoffs.
Activity
cstancu commentedon Sep 23, 2020
Java system properties support is being worked on in #2835 and AWT support should be coming soon. You can track progress here #2545.
liudonghua123 commentedon Nov 25, 2022
I have a similar issue. I use
javax.sound.midi.MidiSystem
API.liudonghua123 commentedon Sep 20, 2023
This error comes from https://github.com/openjdk/jdk/blob/890adb6410dab4606a4f26a942aed02fb2f55387/src/java.desktop/share/classes/com/sun/media/sound/JSSecurityManager.java#L90. It seems
System.getProperty("java.home")
does not work in the executable binary build vianative-image
.And from the doc https://www.graalvm.org/22.1/reference-manual/native-image/Properties/, I should add
-Djava.home=%JAVA_HOME%
arguments when running the executables.