Graal: [native-image] System Properties

Created on 6 Nov 2018  路  7Comments  路  Source: oracle/graal

There are a couple of questions about system properties that aren't covered in docs.

Let's start with simple program which prints system properties:

public class SystemProperties {
  public static void main(String[] args) {
    System.getProperties().forEach((key, value) -> System.out.println(key + ": " + value));
  }
}
  1. According to docs
    > -D= sets a system property;

So it's possible to pass a system property at compile time. Is the property available only at compile time or it's available at run time too? After an experiment

native-image -Dfoo=bar SystemProperties
./systemproperties

it seems like the answer is "compile time only".

  1. There is nothing in docs about passing system properties at start time. But it seems like we could pass them as parameters. So ./systemproperties -Dfoo=bar will print foo: bar. Shouldn't it be mentioned in the docs?

  2. Doesn't passing system properties as parameters with -D prefix break a program semantic for users who migrate from JVM to SVM? Consider a program

public class Args {
  public static void main(String[] args) {
    for (String a: args) { System.out.println(a); }
  }
}

Running it on JVM as java Args -Dfoo=bar prints -Dfoo=bar. Running it on SVM as ./args -Dfoo-bar prints nothing. It's a rare case but it's possible.

documentation native-image

Most helpful comment

Running it on JVM as java Args -Dfoo=bar prints -Dfoo=bar. Running it on SVM as ./args -Dfoo-bar prints nothing. It's a rare case but it's possible

Invoking ./args -Dfoo=bar corresponds to java -Dfoo=bar Args. If you don't want native-image executables to perform -D-processing you can build your image with -H:-ParseRuntimeOptions. Then you will get your String[] args exactly as they are passed to the executable.

All 7 comments

Lets assume you have the following Java Program

public class App {
    public static void main(String[] args) {
        System.getProperties().list(System.out);
    }
}

If you compile that with e.g. native-image -Dfoo=bar App the system property foo will be available at image build-time. I.e. whenever you are in code that is part of your application but executed at image build-time (usually static field initializations & static initializers). Thus if you execute the image above it will not contain foo in the list of properties.

If, on the other hand, you now execute the image with: app -Dfoo=bar it will show foo in the list of properties because you specified it for image run-time.

In other words:

  • Passing -D<key>=<value> to native-image affects properties seen at image build-time.
  • Passing -D<key>=<value> to an image execution affects properties seen at image run-time.

BTW, if you want to make a system property that you specify at image build time also available at image run-time you can "bake" it into your image with:

public class App {
    static final String fooValue = System.getProperty("foo");
    public static void main(String[] args) {
        System.setProperty("foo", fooValue);
        System.getProperties().list(System.out);
    }
}

Now when you build your image with -Dfoo=bar, executing the image will show you property foo.

I.e. whenever you are in code that is part of your application but executed at image build-time (usually static field initializations & static initializers).

Thank you for clarification. It would be nice to have such explanation in the docs.

I still have the 3-rd question BTW.

Running it on JVM as java Args -Dfoo=bar prints -Dfoo=bar. Running it on SVM as ./args -Dfoo-bar prints nothing. It's a rare case but it's possible

Invoking ./args -Dfoo=bar corresponds to java -Dfoo=bar Args. If you don't want native-image executables to perform -D-processing you can build your image with -H:-ParseRuntimeOptions. Then you will get your String[] args exactly as they are passed to the executable.

It would be nice to have such explanation in the docs

I will add that.

Hello, I'm setting a system property -Dlogback.configurationFile="./logback.xml". When I run my application as a jar with this property argument it respects the logback configuration. But when I run my native image ./binary -Dlogback.configurationFile=./logback.xml it is not respecting the configuration. I think this is contradicting the discussion above. Can someone chime in?

But when I run my native image ./binary -Dlogback.configurationFile=./logback.xml it is not respecting the configuration. I think this is contradicting the discussion above.

I depends. Where in Java code is system property logback.configurationFile used? Is that code probably already executed at image build-time (see https://github.com/oracle/graal/blob/master/substratevm/CLASS-INITIALIZATION.md) and thus it's build-time value baked into the native-image? In this case providing a custom value at image-run-time would not have any effect (change what got already determined at image-build time).

I deleted my comment. Explanation: please disregard for now. What I posted before was incorrect. I'm still trying to understand something and may post something again later.

Was this page helpful?
0 / 5 - 0 ratings