Bug 50677 - Allow system property variables in catalina.properties
Allow system property variables in catalina.properties
Product: Tomcat 6
Classification: Unclassified
Component: Catalina
All All
: P2 enhancement (vote)
: default
Assigned To: Tomcat Developers Mailing List
Depends on:
  Show dependency tree
Reported: 2011-01-27 20:54 UTC by Jim Riggs
Modified: 2014-01-09 15:33 UTC (History)
0 users

Proposal A (5.64 KB, patch)
2011-01-27 20:56 UTC, Jim Riggs
Details | Diff
Proposal B (5.39 KB, patch)
2011-01-27 20:56 UTC, Jim Riggs
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Jim Riggs 2011-01-27 20:54:57 UTC
We currently have two hardcoded "variables" that we substitute in catalina.properties, ${catalina.base} and ${catalina.home}.  Is there value in expanding this functionality?  Here is my scenario:

I have several apps, app1, app2, etc.  I have a shared lib directory of jars that the apps share.  In addition, the apps may have several instances running in different "environments" (prod, QA, dev, etc.), and each environment has a corresponding version of the lib directory.  The Tomcat configs for the apps (catalina.base) are version-controlled.

Now, I want each instance of these apps (catalina.base) to be as portable as possible without having to make a bunch of changes for each environment.  So, I want to be able to copy the app1-prod catalina.base to app1-qa and not have to make a lot of local modifications to catalina.properties and friends to make it work.  My init script knows that app1-qa is a QA instance and needs to point to the lib-qa shared directory.  So, I set a system property in the init script via CATALINA_OPTS: -Dshared.lib.dir=/path/to/lib-qa for QA and -Dshared.lib.dir=/path/to/lib-prod for production.  What I would like to do is use this system property via ${property.name} in my common.loader in catalina.properties.  The result is that the catalina.base files are the exact same from a configuration perspective without a bunch of local modifications.

I have created two proposed patches for this functionality.  Both work well, but each one has the potential for some slightly different behavior, so I would like to hear the thoughts of the developers on each.


Proposal A (currently in production use for my environment):

The variable substitution takes place upon retrieval in CatalinaProperties.getProperty(), pulling in the current value of the system property.  This allows other properties defined in catalina.properties to be substituted.  The (potential) downside or risk is that the value of a catalina.property value may change over time if the system properties referenced in its value are changed by the code during the JVM's lifecycle.


Proposal B:

The variable substitution takes place in the class initializer, loadProperties().  This means that every call to CatalinaProperties.getProperty() will return the same result, with system property variables replaced with their value at the time the class was loaded.  The downside of this is that properties set in catalina.properties cannot be used in other properties defined in that file, because they may not yet be set based on the order they are returned by the Enumeration.  This could be worked around, but it would probably take another iteration over the properties (not really a big deal).
Comment 1 Jim Riggs 2011-01-27 20:56:03 UTC
Created attachment 26568 [details]
Proposal A

Substitute on retrieval.
Comment 2 Jim Riggs 2011-01-27 20:56:37 UTC
Created attachment 26569 [details]
Proposal B

Substitute on initialization.
Comment 3 Mark Thomas 2011-01-28 08:32:57 UTC
I'd prefer B and I agree some care is needed with the substitution algorithm.
Comment 4 Konstantin Kolinko 2011-06-15 13:28:20 UTC
One more discussion at users@:
"tomcat 7: common.loader property in catalina.properties does not take ANT style variable"
Comment 5 Konstantin Kolinko 2011-06-15 14:00:38 UTC
I implemented the substitution in r1136043 and it will be in 7.0.17.

I used a different approach to the one proposed above:
I implement substitution for the *.loader properties only. This is the use case that was discussed here and on users@.
Comment 6 Michael Osipov 2014-01-09 15:25:05 UTC
Can we have this in 6.0.x too?

I have a similar usecase. I need to add some JARs from the Oracle client installation. I have defined -Doracle.home=.. in my setenv.sh and then common.loader=${oracle.home}/jlib/oraclepki.jar,...
Comment 7 Michael Osipov 2014-01-09 15:25:52 UTC
My usecase is the same as Yongqin Xu's from the mailing list.
Comment 8 Mark Thomas 2014-01-09 15:33:04 UTC
Re-opening for consideration for back-port to Tomcat 6.