Skip to content

[native-image] java.home property not set #1812

Closed
@karstenw-ro

Description

@karstenw-ro

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

self-assigned this
on Nov 6, 2019
cstancu

cstancu commented on Sep 23, 2020

@cstancu
Member

Java system properties support is being worked on in #2835 and AWT support should be coming soon. You can track progress here #2545.

liudonghua123

liudonghua123 commented on Nov 25, 2022

@liudonghua123

I have a similar issue. I use javax.sound.midi.MidiSystem API.

D:\code\python\fun_player>D:\code\python\fun_player\target\midi_player.exe D:\Downloads\Never-Gonna-Give-You-Up-1.mid
Exception in thread "main" java.lang.Error: Can't find java.home ??
        at com.sun.media.sound.JSSecurityManager.lambda$loadProperties$1(JSSecurityManager.java:90)
        at java.security.AccessController.doPrivileged(AccessController.java:87)
        at com.sun.media.sound.JSSecurityManager.loadProperties(JSSecurityManager.java:87)
        at com.sun.media.sound.JDK13Services.getProperties(JDK13Services.java:192)
        at com.sun.media.sound.JDK13Services.getDefaultProvider(JDK13Services.java:177)
        at com.sun.media.sound.JDK13Services.getDefaultProviderClassName(JDK13Services.java:118)
        at javax.sound.midi.MidiSystem.getDefaultDevice(MidiSystem.java:1096)
        at javax.sound.midi.MidiSystem.getDefaultDeviceWrapper(MidiSystem.java:1078)
        at javax.sound.midi.MidiSystem.getSequencer(MidiSystem.java:379)
        at javax.sound.midi.MidiSystem.getSequencer(MidiSystem.java:339)
        at com.liudonghua.examples.App.main(App.java:27)

D:\code\python\fun_player>java -jar target\midi_player-0.1.0.jar D:\Downloads\Never-Gonna-Give-You-Up-1.mid

D:\code\python\fun_player>
liudonghua123

liudonghua123 commented on Sep 20, 2023

@liudonghua123

I have a similar issue. I use javax.sound.midi.MidiSystem API.

D:\code\python\fun_player>D:\code\python\fun_player\target\midi_player.exe D:\Downloads\Never-Gonna-Give-You-Up-1.mid
Exception in thread "main" java.lang.Error: Can't find java.home ??
        at com.sun.media.sound.JSSecurityManager.lambda$loadProperties$1(JSSecurityManager.java:90)
        at java.security.AccessController.doPrivileged(AccessController.java:87)
        at com.sun.media.sound.JSSecurityManager.loadProperties(JSSecurityManager.java:87)
        at com.sun.media.sound.JDK13Services.getProperties(JDK13Services.java:192)
        at com.sun.media.sound.JDK13Services.getDefaultProvider(JDK13Services.java:177)
        at com.sun.media.sound.JDK13Services.getDefaultProviderClassName(JDK13Services.java:118)
        at javax.sound.midi.MidiSystem.getDefaultDevice(MidiSystem.java:1096)
        at javax.sound.midi.MidiSystem.getDefaultDeviceWrapper(MidiSystem.java:1078)
        at javax.sound.midi.MidiSystem.getSequencer(MidiSystem.java:379)
        at javax.sound.midi.MidiSystem.getSequencer(MidiSystem.java:339)
        at com.liudonghua.examples.App.main(App.java:27)

D:\code\python\fun_player>java -jar target\midi_player-0.1.0.jar D:\Downloads\Never-Gonna-Give-You-Up-1.mid

D:\code\python\fun_player>

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 via native-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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Development

    No branches or pull requests

      Participants

      @cstancu@liudonghua123@karstenw-ro

      Issue actions

        [native-image] java.home property not set · Issue #1812 · oracle/graal