echo $MY_FILE prints "/path/to/some/file"
System.out.println(System.getenv("MY_FILE")); prints null
Additionally, when i print JAVA_HOME (from Eclipse), i too get null. From the shell it echoes /Library/Java/Home
Not sure whether this is relevant, but system i am running is a mac
Any hints?
You likely have not exported the environment variable. In most shells, variables declared in the shell are not exported into the environment of subprocesses unless you do so explicitly, either like this:
export MY_HOME=/somewhere/over/the/rainbow
Or when invoking the program:
MY_HOME=/somewhere/over/the/rainbow java com.example.MyApplication
Also keep in mind that the environment is not global, so changes you make to the environment only affect that process and its subprocesses. If you want to affect the environment of all processes on your system, this has to be configured specially. In most cases, exporting in the shell is what you want.
First try to access a system variable not created by you say
System.out.println(System.getenv("JAVA_HOME"));
If the above work, try rebooting your VM
It appears that environment variable are in some sort of cache, and rebooting is one method to refresh it.
The way to access an environment variable is precisely the way you're aware of. That code works just fine, and the results you receive accurately tell you about the execution environment of the JVM that you're asking the questions of. So,
Environment variables are not 'system variables': they don't have system-scope; changing them in a new terminal will not change them in the process that launches terminals, etc.
They are held by an OS process, and are copied to children of that process. So, children also do not change the environment variables of their parents, when they change their own.
If you launch Eclipse, and then set environment variables in .profile or whatever, and then JVMs launched from Eclipse do not reflect these settings, then you know that Eclipse does not launch a shell that reads your .profile before launching the JVM; it may invoke the shell so that it doesn't read .profile, it may invoke another shell altogether, it may launch the JVM directly, without involving a shell.
If you launch Eclipse after setting those variables, and see the same behavior, then you've learned the same of the process that launches Eclipse.
If you reboot after setting those variables, and see the same behavior, then you've learned the same about your windowing environment.
You can't learn that you're "doing it wrong" when you ask for the values of environment variables in Java, as you're actually doing it right.
You can explore your environment with System.getenv()
Related
iam using the below link to understand environment variables and system properties.
https://docs.oracle.com/javase/tutorial/essential/environment/env.html
The link says environment variables are set by OS and passed to applications.
When i fetch environment variables using System.getenv() it shows me lot of properties which i never set.
So it must be OS (im using macOS) which had set these properties.
Some of the properties in System.getenv() are MAVEN_CMD_LINE_ARGS, JAVA_MAIN_CLASS_1420, JAVA_MAIN_CLASS_1430.
My question is why would OS would like to set the java specific properties in environment variables? Ideally these should be set by JVM (in System.properties()).
P.S.: From whatever i have read on net i understand that environment variables are set by OS and System.properties() are set by JVM
Also if someone can point me to a good link on environment variable and System.properties it will be very helpful. Iam very confused between the two.
Environment variables is an OS concept, and are passed by the program that starts your Java program.
That is usually the OS, e.g. double-click in an explorer window or running command in a command prompt, so you get the OS-managed list of environment variables.
If another program starts your Java program1, e.g. an IDE (Eclipse, IntelliJ, NetBeans, ...) or a build tool (Maven, Groovy, ...), it can modify the list of environment variables, usually by adding more. E.g. the environment variable named MAVEN_CMD_LINE_ARGS would tend to indicate that you might be running your program with Maven.
In a running Java program, the list of environment variables cannot be modified.
System properties is a Java concept. The JVM will automatically assign a lot of
system properties on startup.
You can add/override the values on startup by using the -D command-line argument.
In a running Java program, the list of system properties can be modified by the program itself, though that is generally a bad idea.
1) For reference, if a Java program wants to start another Java program, it will generally use a ProcessBuilder to set that up. The environment variables of the new Java process will by default be the same as the current Java program, but can be modified for the new Java program by calling the environment() method of the builder.
I am setting environment variable in my machine using export MY_KEY=foo. And I am trying to fetch it in JVM using System.getenv("MY_KEY"). This returns null. But running echo $MY_KEY shows foo on the terminal.
I have tried restarting the IDE. Doesn't work, still.
The environment variable is only available to sub processes of the shell that exported it. Did you start your IDE from that shell?
If you want the variable to be available all the time, you need to add it
to the /etc/profile file or create a extra file in /etc/profile.d. It depends on your operating system.
I added some exportable environment variables in my bash_profile and my profile files in the following format export "X=y". This worked as it should, now I want to remove them permanently . I've tried the following methods:
Deleting the exported variables from the bash_profile and the profile files, and saving the files, and calling source ~/.bash_profile and source ~/.profile.
Called "unset X" in terminal window. Before I could call "echo $X" which would display y, now it displays nothing.
Rebooting the Mac Computer.
Still however, whenever I call Java's System.getenv(X), env variable X's value (y) is still returned. What else do I need to do to completely eliminate an env variable from my system in MacOS Mojave?
It appears you believe environment variables are global. That is, modifying the value in one program, such as a running terminal, will affect the value in a different program. That is not how env vars work in a UNIX like OS. Each process is provided a copy of the env vars provided by the parent process. That is, they are inherited from the parent process.
The fact that you have to unset X in a terminal to remove it means that either it is being inherited by the shell from the terminal process or your shell is setting it. In the latter case the specific files read when a shell starts depends on the shell. But /etc/profile is read by most interactive shells so you might want to look there.
You say your Java app is run by Tomcat but failed to mention how Tomcat is started. That is important for the reasons I mention above.
Note that macOS uses a daemon named launchd to manage running most services. Those services are configured via "plist" files. See man launchd.plist. Those launchd config files support defining custom env vars. That is slightly unusual but worth looking at. See if any of the files in ~/Library/LaunchAgents, /Library/LaunchAgents, or /Library/LaunchDaemons mention the env var.
Just to be clear, I DON'T WANT to change the JAVA_HOME during a java command (and take this change into account for said command), but I'm facing a situation where several java commands can be run simultaneously from some ksh scripts, and in those scripts JAVA_HOME is set (and exported) to either a 32-bits or 64-bits version before executing the java command itself.
So I am concerned there could be some "clashes" of some sort... Any advice on how to avoid any "overlaps", if they are even possible?
Note: there can potentially be a lot of script executions at the same time, and >the commands run with 32-bits version of Java cannot be run with 64-bits >version of Java for compatibility issues with other-party processes
Thanks in advance
JAVA_HOME is just a convention and it has no effect on the running JVM.
You can set the JAVA_HOME safely for each script, however do not use export! or you might end up with unexpected results.
Also, usually, the java application is located at JAVA_HOME/bin so you need to make sure that your script is pointing to the correct JVM 32/64.
HTH,
Gal.
Like all environment variables, it's fixed at the start of the command. See, for example, this question (it's about a Python program, but the same concept applies).
However, as others have pointed out, it doesn't actually have any effect on Java commands.
Everywhere I search, it says you can get an environment variable by using System.getenv(str).
It's not working for me. Here's what I am doing:
OS : Mac OS x 10.7
Java 1.6.x
If I do export abc=/hello/ in my terminal and then echo $abc, it gives me the variable. If I close the terminal, reopen it again and do echo $abc, it's gone. To overcome this, I edited my .bash_profile file and inserted export abc=/hello/. Close the terminal, do echo $abc and it works. So I understood that the env variable is permanent now.
Now if in my java console app, I print System.getenv("abc"), it returns null. What am I missing?
The reason that you needed to put the export in your .bash_profile is that setting environment variables in a shell only persist the variables in that shell, and - since you used export - to children of that shell, or in other words, other programs launched by that shell.
If you're running your java code from Eclipse, and you launch Eclipse from a shell with your environment variables set, then your program should see the added environment variables. To launch Eclipse from the shell, you'll need to use the OS X open command:
$ open /Applications/eclipse/Eclipse.app
Alternately, you can set the environment variables within your Eclipse project, and you'll need to do this if you're not launching Eclipse from a shell with the proper environment. In the Run Configurations dialog, look for a tab named Environment. Here you'll find a table for adding environment variables that will be passed to your program.
It's better to add the environment variables to the Run Configuration since that way they'll always be available to your project. Your code doesn't actually care where the environment variables are coming from, and adding them to the project is simpler, and will work the same way on different platforms.
Of course, when you run your program outside Eclipse, you'll need to make sure that the same environment variables exist in the shell where you e.g. run java.
Eclipse does not use the system's env variables unless launched directly from the shell (which is how it is generally launched, by clicking its icon). In that case you will have to explicitly set the required env variables in the environment tab of the run configuration of the program.
I too faced The same issue , I resolved it this way.
Open Terminal
cd to the folder where eclipse.app is located E.g cd /Users/Shared/eclipse/jee-2020-09
Type open Eclipse.app/
Eclipse will now open and will be able to access the system environment variables as well.
Check it using the code:
System.getenv().forEach((k, v) -> {
System.out.println("ENV : " + k + ":" + v);
});