Set Java system properties with a configuration file
Asked Answered
B

7

28

Is it possible to initialize Java system properties using some sort of configuration file?

(ie: can you set java.library.path using a file inside your jar)

EDIT: Clarification: I am asking specifically about initializing the system properties to a value in a file, not setting them later from inside the virtual machine. Yes, you can change system properties to whatever you want very easily after the machine starts up, but the Java system classes will not use the new values.

Practically speaking, this means System.setProperty and System.setProperties are useless for loading native libraries, as JNI will always use the original value of java.library.path to load libraries with. I'm trying to figure out if there's a cleaner alternative to just putting -Djava.library.path=whatever in start up scripts everywhere.

Babylonian answered 18/7, 2011 at 16:36 Comment(3)
You need to implement observer pattern.When the property file change you can have a button on admin screen to get the system read new values or keep checking of for date change on property file.Richter
It is definitely possible to load native libraries from any place you want for your own classes: OSGi exposes a method to do that for bundles via the Bundle-NativeCode manifest header.Phytopathology
or use System.load(String filename) with whatever path you wantHunchback
W
15

There is a way to set java.library.path programatically, see this.

The code is a hack to set the sys_path field on the ClassLoader,

System.setProperty( "java.library.path", "/path/to/libs" );

Field fieldSysPath = ClassLoader.class.getDeclaredField( "sys_paths" );
fieldSysPath.setAccessible( true );
fieldSysPath.set( null, null );
Wendeline answered 24/7, 2011 at 5:35 Comment(2)
the link is goneLumberyard
This will break terribly on JDK 16 where internals are strongly encapsulated by default. Do things the correct way instead of hacking in with reflection.Shrubby
P
16

It would be pretty simple to do yourself:

public static void main(String[] args) {
    Properties p = new Properties();
    p.load(...); // Load the properties from a file in your jar
    for (String name : p.stringPropertyNames()) {
        String value = p.getProperty(name);
        System.setProperty(name, value);
    }
}
Packsaddle answered 18/7, 2011 at 16:44 Comment(4)
OP clarification: "I am asking specifically about initializing the system properties to a value in a file, not setting them later from inside the virtual machine."Gamp
This fails to set the properties before static code blocks are run because they are run before the java main is called. This makes setting things like java.net.keyStore in the main ineffective if code to read your keystore happens in a static block.Birdman
You can use System.setProperties(p); instead of loopCognation
@Cognation using System.setProperties(p) overwrites any properties set previously. So, if you want to preserve previous set properties, either merge the properties using props.putAll(System.getProperties()), replace new Properties() with System.getProperties() or use the for loop to set them one-by-one.Dillingham
W
15

There is a way to set java.library.path programatically, see this.

The code is a hack to set the sys_path field on the ClassLoader,

System.setProperty( "java.library.path", "/path/to/libs" );

Field fieldSysPath = ClassLoader.class.getDeclaredField( "sys_paths" );
fieldSysPath.setAccessible( true );
fieldSysPath.set( null, null );
Wendeline answered 24/7, 2011 at 5:35 Comment(2)
the link is goneLumberyard
This will break terribly on JDK 16 where internals are strongly encapsulated by default. Do things the correct way instead of hacking in with reflection.Shrubby
A
6

Use JAVA_TOOL_OPTIONS environment variable. _JAVA_OPTIONS may also work, but it's not documented at all. The JAVA_TOOL_OPTIONS is weakly documented, but here are some links:

An example of use:

set JAVA_TOOL_OPTIONS=-Dmy.property=sth

When launching JVM you should see a message:

Picked up JAVA_TOOL_OPTIONS: ...
Abstracted answered 5/5, 2017 at 17:35 Comment(2)
Javadocs are for Java6. This didn't work for me in Java 11.Birdman
Works for me (JAVA_TOOL_OPTIONS) on Java 11Evansville
F
1

You cannot initialize them as far as I know, but you can definitely override their values to anything you want, using any source you wish.

Fictive answered 18/7, 2011 at 16:41 Comment(0)
A
1

I think the reason why System.setProperty(key,value) is useless for java.library.path in your program is your application is started, you need set it before your program is running.

Check your native library, if the library have any dependency that not included in the java.library.path, System.load will fail, as if System.setProperty(key, value) does not work as expected.

Amends answered 25/7, 2011 at 2:59 Comment(0)
G
0

You can parse properties file with additional code (another instance of JVM), redirect its output to var and use this variable as parameter to your java invocation. For example:

public class SystemPropertyLoader {
 public static void main(String[] args) throws Exception {
    String file = args[0];//TODO check args
    Properties properties = new Properties();
    InputStream is = new FileInputStream(file);
    properties.load(is);
    is.close();
    StringBuilder builder = new StringBuilder();
    for (Entry e : properties.entrySet()){
        builder.append("-D");
        builder.append(e.getKey());
        builder.append('=');
        builder.append(e.getValue());
        builder.append(' ');
    }
    System.out.println(builder.toString());
 }
}

and

#!/bin/ksh
properties_variable=$(java SystemPropertyLoader input.properties)
Gamp answered 24/7, 2011 at 14:46 Comment(1)
@DouglasTreadwell yeah indeed it is, but OP asked "specifically about initializing the system properties to a value in a file, not setting them later from inside the virtual machine."Gamp
Y
0

If you want to set them before initialization, you should set the properties in your command lines. Something like:

<your command> -D<property_key>=<value>

For example:

mvn clean test -Dtest=MyTest
Yogurt answered 12/6, 2024 at 14:55 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.