views:

378

answers:

4

Hi,

is there a way to add a specific directory to the Windows systemvariable %PATH%? This doesn't seem to work:

String[] cmd = { "cmd", "/c", "set", "PATH=\"%PATH%;c:\\test\"" };
Runtime.getRuntime().exec( cmd );

c:\test\ doesn't appear in System.getenv("PATH"); or in the output of

String[] cmd = { "cmd", "/c", "echo", "%PATH%" };
Runtime.getRuntime().exec( cmd );

What I need is to modify the %PATH%-variable for the current Java-Process under Windows. The reason is, that I need to load some native dll-files which cross-reference each other. So I'd like to add the application-path to the Windows environment.

The next thing I tried was a small JNI-Wrapper for the C-Function "putenv" which looks like this:

JNIEXPORT void JNICALL Java_com_splitscreen_AppletTest_PutEnv_putEnv
  (JNIEnv *env, jobject jobj, jstring val) {

    jboolean iscopy;

    const char *mvalue = (*env)->GetStringUTFChars(
                env, val, &iscopy);

    putenv(mvalue);
}

This is how I call it:

final String curPath = System.getenv( "PATH" );
final PutEnv pe = new PutEnv();
pe.putEnv( "PATH=" + curPath + ";c:\test" );

final String newPath = System.getenv( "PATH" );
System.out.println( newPath );

But the pathes are equal. I'm not sure whether the Map of the Java-System-Environment isn't updated or whether putenv didn't work. Is there a way to check this?

+8  A: 

The reason this doesn't work is that the two exec() invocations start two different shells; the one you set the path in isn't the one you check it in.

It's difficult to change the permanent, systemwide path setting. But you can change the path for the duration of the invocation of one or more programs that you need it for.

Specifically, the thing to do is to write yourself a batch file (.CMD or .BAT, as you please), set the PATH near the beginning, follow that with whatever DOS/Windows commands you'd like executed with that path, and then exec() that script file.


Updating the PATH for the current Java process seems pretty pointless. Java, once running, doesn't care about the path. Or are you running some library code that does?

If you are running DOS/Windows commands from Java using exec(), the above trick will work.


Update: OK, you have library code that for reasons of its own wants the PATH set just so, and you want to give it what it wants.

What I would consider here is to fire up a new JVM. You can use exec(cmd, envp) to start up a new Java application ("yourself," in a pinch) with a custom set of environment variables in envp. Just copy the ones that are already there and manipulate the contents of PATH, if any.

The standard way to start up a new Java app is to create a new ClassLoader, and there are various descriptions on how to accomplish that. But I'm not sure you can use that procedure to come up with a new environment - so exec-ing the JVM may not only be simpler, but possibly the only way.

Carl Smotricz
Hi,yes, I'm running some library code. I edited my question.
Philip
Updated my suggestion, hopefully you'll find the update helpful.
Carl Smotricz
Thanks for your answer, but launching a new JVM isn't an option as I'm running inside an applet (With a signed JAR). I updated my question with another try with JNI.
Philip
+1  A: 

This is not possible with just running a batch file. See here for details.

Your solution doesn't work, because it only modifies the environmental variable in the process level and not in system level.

kgiannakakis
+1  A: 

You can pass paths to where the native libraries are located via the -Djava.library.path option if you are using JNI extensions, this may also work for your exec case. The other option is to launch the java app from a batch file and edit the PATH settings in the command interpreter "before" you launch the java app, the java app will inherit this PATH settings.

NASA WorldWind uses native libraries and can be run as an Applet, here is a howto on setting this up with JNLPAppletLauncher. What this basically does is detect the OS, fetch appropriate native libraries, save them in a location in default jvm path and execute. Calling exec from a Java applet violates all sorts of sane security and sandboxing principles and I would really avoid it.

whatnick
+1 for java.library.path, I'd say it's worth a try! But apparently the app is an applet, so unfortunately the batch approach seems to be out :(
Carl Smotricz
A: 

You can try to use setenv.exe (from here) instead of cmd /c.
or setx.exe from Microsoft.

Carlos Heuberger