oracle / graal

GraalVM compiles Java applications into native executables that start instantly, scale fast, and use fewer compute resources 🚀
https://www.graalvm.org
Other
20.39k stars 1.64k forks source link

Java system properties are inconsistent between traditional JDK and native image #2835

Open ziyilin opened 4 years ago

ziyilin commented 4 years ago

Describe the issue

Java system properties are changed from native image to OpenJDK. Some properties are removed, and some properties' values are changed. When user call System.getProperty, he/she may expect a consistent value with OpenJDK version. Or at least a warning is reported at build time. We propose https://github.com/oracle/graal/pull/2834 to fix this issue.

Steps to reproduce the issue Run this test with OpenJDK will print out the java.home location, but with native image will get a NPE.

import java.io.File;

public class TestUnsupportedProperty {

    public static void main(String[] args){
        boolean suc = true;
        try{
            testSunBootClassPath();
        } catch ( Throwable t){
            t.printStackTrace();
            suc = false;
        }
        if (!suc){
            System.exit(1);
        }
    }

    private static void testSunBootClassPath(){
        String ret=System.getProperty("java.home");
        File path = new File(ret);
        System.out.println(path.getAbsolutePath());
    }
}

Describe GraalVM and your environment:

More details The exception thrown:

java.lang.NullPointerException
        at java.io.File.<init>(File.java:278)
        at test.property.TestUnsupportedProperty.testSunBootClassPath(TestUnsupportedProperty.java:48)
        at test.property.TestUnsupportedProperty.main(TestUnsupportedProperty.java:36)
CrazyHZM commented 1 year ago

@christianwimmer Has this problem been solved?

christianwimmer commented 1 year ago

We are still not setting the java.home system property at image run time by default, and do not plan to change that. Because there is just no "JDK home directory" around at image run time, so setting java.home to, for example, the directory where the native image is located in is misleading - files that might be expected to be in that directory are not there.

CrazyHZM commented 1 year ago

So the user should specify that property at startup, right?

christianwimmer commented 1 year ago

So the user should specify that property at startup, right?

Correct. You can use -Djava.home=... on the command line when starting the image. Or if you have an application where you can compute the system property value, you can also use System.setProperty("java.home", ...) early in your application.

CrazyHZM commented 1 year ago

Thanks for the answer. @christianwimmer

lazystone commented 9 months ago

Could someone with OpenJDK contributor access maybe create a small proposal into OpenJDK project:

One of the problems can be easily solved in OpenJDK codebase:

Exception in thread "main" java.lang.Error: java.home property not set
    at sun.awt.FontConfiguration.findFontConfigFile(FontConfiguration.java:182)

It fails because of this code in FontConfiguration.findFontConfigFile():

foundOsSpecificFile = true; // default assumption.
String javaHome = System.getProperty("java.home");
if (javaHome == null) {
    throw new Error("java.home property not set");
}

But not having os specific font config is actually considered to be "normal" a bit below.

private File findFontConfigFile(String dir):

// ...
// At the very end of the method:
foundOsSpecificFile = false;

configFile = findImpl(baseName);
if (configFile != null) {
    return configFile;
}
if (FontUtilities.debugFonts()) {
    logger.info("Did not find a fontconfig file.");
}
return null;

So maybe it's better to have something like this instead in FontConfiguration.findFontConfigFile():

String javaHome = System.getProperty("java.home");
if (javaHome == null) {
  foundOsSpecificFile = false;
  fontConfigFile = null;
  return;
}
foundOsSpecificFile = true; // default assumption.