What is the best/foolproof way to get the values of environment variables in Windows when using J2SE 1.4 ?
You can use getEnv() to get environment variables:
String variable = System.getenv("WINDIR");
System.out.println(variable);
I believe the getEnv() function was deprecated at some point but then "undeprecated" later in java 1.5
ETA:
I see the question now refers specifically to java 1.4, so this wouldn't work for you (or at least you might end up with a deprecation warning). I'll leave the answer here though in case someone else stumbles across this question and is using a later version.
There's a switch to the JVM for this. From here:
Start the JVM with the "-D" switch to pass properties to the application
and read them with the System.getProperty() method.
SET myvar=Hello world
SET myothervar=nothing
java -Dmyvar="%myvar%" -Dmyothervar="%myothervar%" myClass
then in myClass
String myvar = System.getProperty("myvar");
String myothervar = System.getProperty("myothervar");
You have definitely no way to access environment variables straigthly from java API. The only way to achieve that with Runtime.exec with such a code :
Process p = null;
Runtime r = Runtime.getRuntime();
String OS = System.getProperty("os.name").toLowerCase();
// System.out.println(OS);
if (OS.indexOf("windows 9") > -1) {
p = r.exec( "command.com /c set" );
}
else if ( (OS.indexOf("nt") > -1)
|| (OS.indexOf("windows 2000") > -1 )
|| (OS.indexOf("windows xp") > -1) ) {
// thanks to JuanFran for the xp fix!
p = r.exec( "cmd.exe /c set" );
}
Although you can access Java variables thanks to System.getProperties();
But you would only get some env variables mapped by JVM itself, and additional data you could provide on java command line with "-Dkey=value"
For more information see http://www.rgagnon.com/javadetails/java-0150.html
Pass them into the JVM as -D system properties, for example:
java -D<java var>=%<environment var>%
That way you don't become tied to a particular OS.
Map<String, String> env = System.getenv();
for (String envName : env.keySet()) {
System.out.format("%s=%s%n", envName, env.get(envName));
}
Apache Commons Exec provides with "org.apache.commons.exec.environment.EnvironmentUtils" a way to get the environment variables on JDK's prior 1.5:
(String) EnvironmentUtils.getProcEnvironment().get("SOME_ENV_VAR")
Related
I have a java process running as windows server using prcorun (http://commons.apache.org/proper/commons-daemon/); unfortunatly I have to launch an external legacy command written in C/C++.
both
Process myProcess = Runtime.getRuntime().exec(command);
and
Process myProcess = new ProcessBuilder(command, arg).start();
work well when java is launched as a stand-alone application, but when I start java as service it replies
command not found
also with
Process myProcess = Runtime.getRuntime().exec("dir");
command not found
I think is a problem due to windows services.
Any suggestion?
I would try to do a quick test and print the PATH environment variable in your service. What I usually found when you run some command as a service, the PATH might not be totally available (which can also explain why DIR is not working for you). If that the case, when starting the service, you have to make sure the PATH include both the normal bin and your legacy bin.
As the error says, the command is not found in the path. You'll need to set the environment variable PATH to the child process's environment. Look at exec(cmd, String[] env) method. You can create an array of environment variables (key value pairs) and pass it to exec().
In my case I used
cmd /c <<YOUR COMMAND>>
eg.
Process myProcess = Runtime.getRuntime().exec("cmd /c dir");
also I added the envinronments. as suggested by smurf
private static String[] getEnv() {
Map<String, String> env = System.getenv();
String[] envp = new String[env.size()];
int i = 0;
for (Map.Entry<String, String> e : env.entrySet()) {
envp[i++] = e.getKey() + "=" + e.getValue();
}
return envp;
}
...
Process myProcess = Runtime.getRuntime().exec("cmd /c dir",getEnv());
Alternative to java.lang.Runtime.exec() that can execute command lines as a single string?
I need to set an environment variable in OS X El Capitan so it can be read by java with System.getenv(myVar). How can I do it? Of course the variable must be only readable by the user who created it (and the admin probably).
The default shell on OS X is bash.
export FRED="Hello"
and then you can use something like
String fred = System.getenv("FRED");
System.out.println(fred);
I know why it happened. There's a bug in Oracle java where SecurityManager sm = getSecurityManager(); returns always a null string (sm = null). After updating java 8.0.51 to 8.0.65 it worked perfectly. The same happens on some version of Oracle java for linux.
The affected routine is this:
public static String getenv(String name)
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How do I set environment variables from Java?
I'm trying to set an environment variable, and read it back to verify it was actually set.
I've got the following :
import java.io.IOException;
public class EnvironmentVariable
{
public static void main(String[] args) throws IOException
{
Runtime.getRuntime().exec("cmd.exe set FOO=false");
String s = System.getenv("FOO");
System.out.println(s);
}
}
However, it appears that FOO is always null, meaning its probably not set correctly.
Do I have the exec command correct? The javadocs state it can take a string argument as the command.
Any ideas?
There are overloaded exec methods in which you can include an array of environment variables. For example exec(String command, String[] envp).
Here's an example (with proof) of setting an env variable in a child process you exec:
public static void main(String[] args) throws IOException {
String[] command = { "cmd", "/C", "echo FOO: %FOO%" };
String[] envp = { "FOO=false" };
Process p = Runtime.getRuntime().exec(command, envp);
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String s = reader.readLine();
System.err.println(s);
}
However, that sets the variable in the env of the created process, not of your current (Java) process.
Similarly, if you are creating a process from Ant (as you mention in comments to aix) using the exec task, then you can pass environment variables to the child process using nested env elements, e.g.
<exec executable="whatever">
<env key="FOO" value="false"/>
</exec>
This won't work. When you start a new process, that process receives a copy of the environment. Any changes it then makes to environment variables are made within that copy, and at no point will become visible to the caller.
What are you actually trying to achieve?
By running "cmd.exe", you start a new process, which receives the new environment variable, however the java process does not get that new environment variable set this way.
In Unix/Windows, each process has it's own set of environment variables and inherits the environment variables from it's parent during process creation.
System.getenv() only returns the environment variables that were set when the process was started, as far as I see there is no way to change the environment variables of the java process itself.
The only way you can check if the set works is by starting a small batch script where you set and do the check in one process.
It's null because you launch another cmd.exe: it's a different environment from the one of your Java application (cf aix answer).
I don't think the Java runtime can change an environment variable: it can read them, but can't change them.
If you want to change a system property available in your executing JVM, use System.setProperty(String key, String value).
System.getenv(name) needs the name of environment variable.
I am trying to call Runtime.exec(String[], String[], File), the secondary parameter need an array of environment variable, I am not sure whether subprocess will inherit environment variables from current process if I specified this parameter.
For example, if I pass new String[]{"NEWDIR=/home"} as secondary parameter and current java process has environment OLDDIR=/var, what is the return value of System.getenv("OLDDIR") in the subprocess?
updated:
Sorry, I have to use Java 1.4 and it seems that System.getenv() was introduced in 1.5?
Map<String, String> env = System.getenv();
for (String envName : env.keySet()) {
System.out.format("%s=%s%n", envName, env.get(envName));
}
System.getenv() will return a Map<String,String> with all of the environment variables.
But you could just as easily switch to ProcessBuilder which is a more convenient API to start new processes.
With ProcessBuilder you can simply call environment() and get a Map that contains existing environment variables and which you can manipulate how you want: i.e., if you add something to it, then that will be added to the new processes environment variables. If you remove something from it, it will not be present in the new process.
If you run an external shell, you can use it to set environment variables. e.g.
bash -c ENV1=hi ENV2=bye echo $ENV1 $ENV2
This only works if you have a UNIX shell (or cygwin)
You should migrate away from Java 1.4 and Java 5.0. Even Java 6 you might consider upgrading to Java 7.
I have an application which uses DirectByteBuffers to store data, but I'd like to know what MaxDirectMemorySize is so I don't accidentally exceed it.
Without configuring this manually, how can I figure out, from within the program, what MaxDirectMemorySize is?
The accepted answer only works if the option is explicitly specified on the command line. As of Java 6, you can access the option directly using the HotSpotDiagnosticMXBean. The following Java 7 code can read it conveniently:
final HotSpotDiagnosticMXBean hsdiag = ManagementFactory
.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
if (hsdiag != null) {
System.out.println(hsdiag.getVMOption("MaxDirectMemorySize"));
}
Note that this may return a value of zero, meaning to use the default setting, which is equal to Runtime.getRuntime().maxMemory(). For example, with Oracle JDK 7u71 64-bit on Windows 7, this returns 3,690,987,520.
Alternatively, if you're willing to resort to accessing the sun.misc package, it's available directly by calling sun.misc.VM.maxDirectMemory().
Yuu can get ALL JVM parameters with...
RuntimeMXBean RuntimemxBean = ManagementFactory.getRuntimeMXBean();
List<String> args=RuntimemxBean.getInputArguments();
for(int i=0;i<args.size();i++) {
System.out.println(args.get(i));
}