*
The moose likes Tomcat and the fly likes JAVA_OPTS Variable Handling (Environment Var vs. System Property) Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Products » Tomcat
Bookmark "JAVA_OPTS Variable Handling (Environment Var vs. System Property)" Watch "JAVA_OPTS Variable Handling (Environment Var vs. System Property)" New topic
Author

JAVA_OPTS Variable Handling (Environment Var vs. System Property)

Mike London
Ranch Hand

Joined: Jul 12, 2002
Posts: 1043
If I set an environment variable in the shell called JAVA_OPTS and export it before running a regular Java application, then the getEnv() will find that variable, but getProperty() will not.

--------------

Yet, if I create a simple Servlet where I have set up the "setenv.sh" to extend Tomcat and include JAVA_OPTS there, then the value DOES show up in getProperty() and as an environment variable.

--------------

So, my question is does Tomcat read this value and convert it to system properties for the JVM or exactly what is happening?

Would welcome any insights as to what is happening here.

Thanks.

-mike
Karthik Shiraly
Ranch Hand

Joined: Apr 04, 2009
Posts: 489
    
    5
Tomcat itself does not, but its startup scripts (catalina.bat / catalina.sh) do; they insert value of JAVA_OPTS env var into the command line that starts up Tomcat.
If JAVA_OPTS has a value like
JAVA_OPTS="-Doption1=value1 -Doption2=value2..."

getEnv() will show the env var value as "-Doption1=value1 -Doption2=value2..."
while getProperty() will return the correct value for each key.
Mike London
Ranch Hand

Joined: Jul 12, 2002
Posts: 1043
Karthik Shiraly wrote:Tomcat itself does not, but its startup scripts (catalina.bat / catalina.sh) do; they insert value of JAVA_OPTS env var into the command line that starts up Tomcat.
If JAVA_OPTS has a value like
JAVA_OPTS="-Doption1=value1 -Doption2=value2..."

getEnv() will show the env var value as "-Doption1=value1 -Doption2=value2..."
while getProperty() will return the correct value for each key.


This is good information, but as I understand it, JAVA_OPTS is a "known variable" that the JVM recognizes, correct?

My question remains as to how these values passed to Tomcat end up as properties. Tomcat is doing some "System.setProperty('''')" behind the scenes?

I tried to add a custom "-Dvariable.name='something'" entry in our setenv.sh file, but it did not become a property (was null) I could extract. So, what exactly are the rules for what's allowed in JAVA_OPTS? Our application seems to be using some custom ones, but perhaps they are in some list I don't have.

Implementation of JAVA_OPTS is difficult to find.

Thanks again.

mike
Karthik Shiraly
Ranch Hand

Joined: Apr 04, 2009
Posts: 489
    
    5
JAVA_OPTS is not a variable recognized by JVM (atleast by the Oracle/Sun/OpenJDK JVM). A search of OpenJDK source code including the hotspot native C++/C code shows that while it does have knowledge of some env vars like JAVA_HOME / JRE_HOME / CLASSPATH / _JAVA_OPTIONS, it does not refer to JAVA_OPTS anywhere.

My question remains as to how these values passed to Tomcat end up as properties. Tomcat is doing some "System.setProperty('''')" behind the scenes?

If you pass a command line arg like "-Dkey=value" to java process, it automatically ends up as a system property.
JAVA_OPTS is a variable that is being used only by tomcat's startup scripts, not by tomcat's core java components nor by JVM.
catalina.sh has a line like

This is where it spawns the JVM process and passes in value of JAVA_OPTS.
If the value of JAVA_OPTS has any strings of the form "-D<key>=value", those keys end up as system properties. But JAVA_OPTS can also have other flags like "-Xmx=512M"; those won't be treated as system properties.

I tried to add a custom "-Dvariable.name='something'" entry in our setenv.sh file, but it did not become a property (was null) I could extract.

I tried the same (on Ubuntu Lucid server) and it works for me. Here's my listing, if it helps:


Check that your catalina.sh is including your setenv.sh. It should have a line like this:


The test servlet which prints out System.getEnv() and System.getProperties() shows the following for me:


Implementation of JAVA_OPTS is difficult to find.

It's all in catalina.sh, nowhere else. My guess is that your setenv.sh is not being included/executed. Check its user/group/file permissions too.
Mike London
Ranch Hand

Joined: Jul 12, 2002
Posts: 1043
Karthik Shiraly wrote:JAVA_OPTS is not a variable recognized by JVM (atleast by the Oracle/Sun/OpenJDK JVM). A search of OpenJDK source code including the hotspot native C++/C code shows that while it does have knowledge of some env vars like JAVA_HOME / JRE_HOME / CLASSPATH / _JAVA_OPTIONS, it does not refer to JAVA_OPTS anywhere.

My question remains as to how these values passed to Tomcat end up as properties. Tomcat is doing some "System.setProperty('''')" behind the scenes?

If you pass a command line arg like "-Dkey=value" to java process, it automatically ends up as a system property.
JAVA_OPTS is a variable that is being used only by tomcat's startup scripts, not by tomcat's core java components nor by JVM.
catalina.sh has a line like

This is where it spawns the JVM process and passes in value of JAVA_OPTS.
If the value of JAVA_OPTS has any strings of the form "-D<key>=value", those keys end up as system properties. But JAVA_OPTS can also have other flags like "-Xmx=512M"; those won't be treated as system properties.

I tried to add a custom "-Dvariable.name='something'" entry in our setenv.sh file, but it did not become a property (was null) I could extract.

I tried the same (on Ubuntu Lucid server) and it works for me. Here's my listing, if it helps:


Check that your catalina.sh is including your setenv.sh. It should have a line like this:


The test servlet which prints out System.getEnv() and System.getProperties() shows the following for me:


Implementation of JAVA_OPTS is difficult to find.

It's all in catalina.sh, nowhere else. My guess is that your setenv.sh is not being included/executed. Check its user/group/file permissions too.


Thanks very much! This is a terrific reply. My issue with my -D property not being seen was that I did not restart the server.

Thanks again!!!

-mike
Karthik Shiraly
Ranch Hand

Joined: Apr 04, 2009
Posts: 489
    
    5
You're welcome! Good old restart...it solves most problems in computing .
Mike London
Ranch Hand

Joined: Jul 12, 2002
Posts: 1043
Karthik Shiraly wrote:You're welcome! Good old restart...it solves most problems in computing .


I had forgotten (or never really knew/understood) about the -D command line switch for the Java program. Now it works even with java applications, as you would expect.

In any case, thanks so much for the obvious time and thought you put into your replies.

Best,

-mike
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 15952
    
  19

Caution: Use of environment (system) properties to provide application options or other information is something I strongly discourage for a number of reasons. Not the least of which is that since a J2EE webapp server can be hosting multiple applications, there's always a possibility that the options for one application can interfere with options for another, since they're sharing a global environment.

A better place to set options is in one of the following places:

1. Tomcat Context definition (use JNDI to read the option value)

2. The application's WEB-INF/web.xml file (you would also set default values for JNDI options here).

3. A properties file located within the application classpath (this requires rebuilding the app to change)

4. A properties file located at an absolute filesystem location (requires hard-coding stuff dependent on the server's filesystem layout unless you use one of the preceeding to specify the path.

4. Storing options in a database. This can run into issues like the use of environment properties does, since the database might be shared between multiple apps.


Customer surveys are for companies who didn't pay proper attention to begin with.
Mike London
Ranch Hand

Joined: Jul 12, 2002
Posts: 1043
Tim Holloway wrote:Caution: Use of environment (system) properties to provide application options or other information is something I strongly discourage for a number of reasons. Not the least of which is that since a J2EE webapp server can be hosting multiple applications, there's always a possibility that the options for one application can interfere with options for another, since they're sharing a global environment.

A better place to set options is in one of the following places:

1. Tomcat Context definition (use JNDI to read the option value)

2. The application's WEB-INF/web.xml file (you would also set default values for JNDI options here).

3. A properties file located within the application classpath (this requires rebuilding the app to change)

4. A properties file located at an absolute filesystem location (requires hard-coding stuff dependent on the server's filesystem layout unless you use one of the preceeding to specify the path.

4. Storing options in a database. This can run into issues like the use of environment properties does, since the database might be shared between multiple apps.


Good info, thanks. I never have understood how to use/setup JNDI. Haven't found any good references to explain whether it's something I would (could) do locally or if it's mainly for an enterprise environment.

-mike
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 15952
    
  19

Well, Tomcat is an Enterprise environment. Java Enterprise Edition (JEE).

JNDI can be a little confusing, but it's a useful skill to have. Its name literally means Java Naming and Directory Interface, and it's an abstract mechanism for retrieving data based on a hierarchical "directory path". The actual backing store for JNDI can be one of a number of things. LDAP/Active Directory for example. Or, in the case of Tomcat, it's an internal structure built into the Tomcat server.

The most frequently-seen JNDI in J2EE is the definition given for JDBC Connection pools, where the directory name is typically something like "java:comp/env/jdbc/mypool". In the Tomcat Context you would have defined a "jdbc/mypool" name and associated it with the resource definition of that pool.

For parameter-style string values, here's an example from one of my Context files:


Here I'm defining a base URL of type String to the JNDI URL "java:comp/env/server/baseURL.

This has a corresponding web.xml entry:


Note that this defines the default value if I didn't override via Context - whose "override="false" means the opposite of what you think - it means whether or not web.xml should override the Context, not the other way around.

I don't have the actual JNDI code, since this particular app is using Spring, which can automatically do the lookup and stuff the value into a POJO bean for me, but the basic process is simply to get the JNDI baseContext, lookup a relative path from there, then cast the returned value (if any) to the appropriate data type (String, in this particular case). There are lots of examples available, since this is basic JNDI lookup. I just don't happen to have one handy right now.
Mike London
Ranch Hand

Joined: Jul 12, 2002
Posts: 1043
Tim Holloway wrote:Well, Tomcat is an Enterprise environment. Java Enterprise Edition (JEE).

JNDI can be a little confusing, but it's a useful skill to have. Its name literally means Java Naming and Directory Interface, and it's an abstract mechanism for retrieving data based on a hierarchical "directory path". The actual backing store for JNDI can be one of a number of things. LDAP/Active Directory for example. Or, in the case of Tomcat, it's an internal structure built into the Tomcat server.

The most frequently-seen JNDI in J2EE is the definition given for JDBC Connection pools, where the directory name is typically something like "java:comp/env/jdbc/mypool". In the Tomcat Context you would have defined a "jdbc/mypool" name and associated it with the resource definition of that pool.

For parameter-style string values, here's an example from one of my Context files:


Here I'm defining a base URL of type String to the JNDI URL "java:comp/env/server/baseURL.

This has a corresponding web.xml entry:


Note that this defines the default value if I didn't override via Context - whose "override="false" means the opposite of what you think - it means whether or not web.xml should override the Context, not the other way around.

I don't have the actual JNDI code, since this particular app is using Spring, which can automatically do the lookup and stuff the value into a POJO bean for me, but the basic process is simply to get the JNDI baseContext, lookup a relative path from there, then cast the returned value (if any) to the appropriate data type (String, in this particular case). There are lots of examples available, since this is basic JNDI lookup. I just don't happen to have one handy right now.


Thanks Tim. This is great info.

I have heard that Tomcat should not really be used for production apps, but that may not be true anymore.

Appreciate your excellent follow up.

-mike
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 15952
    
  19

I don't know where you heard Tomcat wasn't suitable for production. It runs in production daily on uncounted sites, including the ones I work with. I've been using Tomcat in production since at least 2003.

While it doesn't implement the full J2EE stack, it is also embedded into full-stack JEE servers such as JBoss (now WildFly) and JoNaS. And many webapps either don't need the missing parts of the J2EE standard such as EJBs and JMS or can work with Tomcat's equivalents.
Mike London
Ranch Hand

Joined: Jul 12, 2002
Posts: 1043
Tim Holloway wrote:I don't know where you heard Tomcat wasn't suitable for production. It runs in production daily on uncounted sites, including the ones I work with. I've been using Tomcat in production since at least 2003.

While it doesn't implement the full J2EE stack, it is also embedded into full-stack JEE servers such as JBoss (now WildFly) and JoNaS. And many webapps either don't need the missing parts of the J2EE standard such as EJBs and JMS or can work with Tomcat's equivalents.


Sounds good. Clearly I had bad information and I've also had nothing but good experiences with Tomcat.

Thanks again.

-mike
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: JAVA_OPTS Variable Handling (Environment Var vs. System Property)
 
Similar Threads
heap size in apache tomcat 5.x
System Properties
how to use the environment variables ?
out of memory exception in web application!
Setting environment variable for Java on Unix OS