Tomcat 8 - context.xml use Environment Variable in Datasource
Asked Answered
S

2

23

I have a Tomcat 8 project that uses a datasource (see below)

<Resource auth="Container" 
          name="jdbc/JtmDS"  
          driverClassName="org.apache.derby.jdbc.EmbeddedDriver" 
          type="javax.sql.DataSource" 
          username="xfer"
          password="xfer10" 
          url="jdbc:derby:/home/PUID/tm/control/JtmDB"                    
          initialSize="25"
          maxTotal="100" 
          maxIdle="30" 
          maxWaitMillis="10000"                                      
          removeAbandonedOnBorrow="true"
          removeAbandonedTimeout="20" />

This works perfectly well.

However the url is a hard-coded path /home/PUID/tm/control/JtmDB

When this gets into production the PUID part of the path will differ across numerous systems. I have an environment variable set export PUID=abcd The rest of the application is able to use things like System.getenv( ) or ${env:PUID} as and where appropriate.

These all work fine.

My question is very simply: How can I make the PUID value in my context.xml a variable that can be read from an environment variable?

Sachasachem answered 26/6, 2017 at 14:17 Comment(4)
Could you try url="jdbc:derby:${PUID}" ?Mensuration
I did try that and have done again on your suggestion. No good. It treats /home/${PUID}/tm/control/JtmDB as a literal PATH.Sachasachem
Have the same requirement, did you ever resolve this?Curtate
I'm afraid I didn't as per the question. But I resolved it by moving the database into a generic location. /opt/app/db where it sits for all implementations.Sachasachem
S
26

I finally discovered what I actually needed to do here.... Quite simple in the end.

I passed in a java parameter to Tomcat at runtime as shown below.

I added the following bits to setenv.sh

export PUID=abcd

JAVA_OPTS=-Dpuid=${PUID} 

Then edited my context.xml as shown here

<Resource auth="Container" 
          name="jdbc/JtmDS"  
          driverClassName="org.apache.derby.jdbc.EmbeddedDriver" 
          type="javax.sql.DataSource" 
          username="xfer"
          password="xfer10" 
          url="jdbc:derby:/home/${puid}/tm/control/JtmDB"                    
          initialSize="25"
          maxTotal="100" 
          maxIdle="30" 
          maxWaitMillis="10000"                                      
          removeAbandonedOnBorrow="true"
          removeAbandonedTimeout="20" />

So now my Tomcat installation will read this and be able to use a different path for each different PUID.


Background: This works because Tomcat will automatically perform variable substition in its configuration files:

Tomcat configuration files are formatted as schemaless XML; elements and attributes are case-sensitive.

Apache Ant-style variable substitution is supported; a system property with the name propname may be used in a configuration file using the syntax ${propname}. All system properties are available including those set using the -D syntax, those automatically made available by the JVM and those configured in the $CATALINA_BASE/conf/catalina.properties file.

Apache Tomcat 9 Configuration Reference - Overview

The part:

JAVA_OPTS=-Dpuid=${PUID}

describe above is necessary because Tomcat will only read Java system properties (which are provided by the JVM), but not environment variables (which are provided by the OS/runtime libraries that the JVM is running on). The parameter -D sets a Java system property from the environment variable of the same name.

Sachasachem answered 26/3, 2018 at 13:30 Comment(5)
Thanks for that answer. It works for other values as well.Pithy
Absolutely. You can put anything you want in there.Sachasachem
Keep in mind that this exposes the env var values in the command line if you query something like ps -eo args. This can potentially be grabbed by instrumentation agents and send to lots of places, which may leak passwords and other secrets.Ridotto
My I ask in which context you're running the setenv.sh? Facing the same problem locally, but I am not able to the Java Opts through with this...Appreciative
Its been a while since I looked at this. This was run via a Command Line so the setenv.sh was automatically read by Tomcat. We just needed to make sure the correct variable were in there. If you can't change setenv.sh then I'm not sure how you will be able to do this.Sachasachem
C
3

Either you set the JVM env. variables as mentioned by sleske above.

If you like to use the system env. variables you have to set the JAVA_OPTS: -Dorg.apache.tomcat.util.digester.PROPERTY_SOURCE=org.apache.tomcat.util.digester.EnvironmentPropertySource
For more information have a look at this entry: inject environment variables in tomcat catalina.properties [Kubernetes]

Hope this helps at least one person! (:

Chiekochien answered 8/2, 2023 at 8:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.