16

Can I set java.library.path programmatically from java code itself?

The following doesn't work.

    System.setProperty("java.library.path", "/blah");
Fakrudeen
  • 5,778
  • 7
  • 44
  • 70

5 Answers5

23

Maybe this will help: Setting "java.library.path" programmatically

When messing around with JNI, one has to set the java.library.path accordingly. Unfortunately the only way is to add a system property before the application is started:

java -Djava.library.path=/path/to/libs  

Changing the system property later doesn’t have any effect, since the property is evaluated very early and cached. But the guys over at jdic discovered a way how to work around it. It is a little bit dirty – but hey, those hacks are the reason we all love Java…

System.setProperty( "java.library.path", "/path/to/libs" );  
Field fieldSysPath = ClassLoader.class.getDeclaredField( "sys_paths" );  
fieldSysPath.setAccessible( true );  
fieldSysPath.set( null, null );  

Explanation

At first the system property is updated with the new value. This might be a relative path – or maybe you want to create that path dynamically.

The Classloader has a static field (sys_paths) that contains the paths. If that field is set to null, it is initialized automatically. Therefore forcing that field to null will result into the reevaluation of the library path as soon as loadLibrary() is called…

Community
  • 1
  • 1
secmask
  • 7,649
  • 5
  • 35
  • 52
  • +1 - Very cool hack - I will try this as the last resort [this is very cool, but horrible for maintainability!]. – Fakrudeen Aug 02 '11 at 09:20
  • Please quote the relevant parts of the article in your answer as links can go dead (which yours has). – Emily L. Sep 29 '16 at 13:49
  • You should be really careful with this, not only is it implementation based, but it might also cause unexpected exceptions when a concurrent thread tries to load a native library and has just passed the `null` check for this field when you set it to `null` – Marcono1234 Mar 27 '19 at 16:49
  • @secmask what if I have this code wrapped in a jar? How do I find out my "/path/to/libs" ? – GuyTal Jan 07 '20 at 21:10
  • @GuyTal did you mean your native library(.so or .dll) wrap in jar? then you will need to extract it somewhere outside, on file system first, see https://stackoverflow.com/questions/20389255/reading-a-resource-file-from-within-jar – secmask Jan 08 '20 at 04:02
19

No you can't. This property is a read only value. You can change it at JVM launchin time with:

-Djava.library.path=your_path

If you want to load a library from a specific location, you can use System.load(libraryPath) instead with the full path to the library.

Manuel Selva
  • 18,554
  • 22
  • 89
  • 134
  • I wanted to accept both the answers, but as I can accept only one I will go with this,as the cool hack relies on implementation details. – Fakrudeen Aug 02 '11 at 09:24
0

I'm just quoting from the link provided by secmask (https://cedarsoft.com/blog.html), in case the link goes dead:

Changing the system property java.library.path later doesn’t have any effect, since the property is evaluated very early and cached. But the guys over at jdic discovered a way how to work around it. It is a little bit dirty – but hey, those hacks are the reason we all love Java.

System.setProperty("java.library.path", "/path/to/libs");
Field fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths");
fieldSysPath.setAccessible(true);
fieldSysPath.set(null, null);

Explanation:

At first the system property is updated with the new value. This might be a relative path – or maybe you want to create that path dynamically. The Classloader has a static field (sys_paths) that contains the paths. If that field is set to null, it is initialized automatically.Therefore forcing that field to null will result into the reevaluation of the library path as soon as loadLibrary() is called.

MNos
  • 520
  • 6
  • 11
-1

Yes it will read the Environment Variables. Following is the code for setting the Environment variable using the ini4j.

import java.io.IOException;
import org.ini4j.Reg;


public class SettingWinEnvironmentUsing_ini4j {

    public static void main(String args[])
    {
        System.out.println("Setting System Environment Variables");

        Reg reg = new Reg();
        Reg.Key env = reg.add("HKEY_CURRENT_USER\\Environment");
        env.put("RR_PROPERTY_PATH", "c:\\path");
        try {
            reg.write();
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println(env.get("RR_PROPERTY_PATH"));
    }
}

You can find the ini4j jar at

http://cropforge.org/plugins/scmsvn/viewcvs.php/IAPlugin/lib/ini4j-0.5.2-SNAPSHOT.jar?rev=656&root=icisjavatools&view=log

Emily L.
  • 5,673
  • 2
  • 40
  • 60
-5
import java.util.Map;

public class ReadingEnvironment {

    public static void main(String[] args) {
        System.out.println("Reading System Environment Variables:\n");
        // System.out.println(System.getenv());
        Map<String, String> env = System.getenv();
        for (String envName : env.keySet()) {
            System.out.format("%s=%s%n", envName, env.get(envName));
        }
    }
}
Adriano Carneiro
  • 57,693
  • 12
  • 90
  • 123