简体   繁体   中英

Heroku Tomcat based Deployment : context.xml Environment variables

I have deployed a Java Tomat application to Heroku platform. I needed a JDBC datasource. So I have added a "local" context.xml in the "META-INF" directory through maven war plugin.

Heroku provides a system environment variable JDBC_DATABASE_URL that should have served my purpose like below when added to context.xml :

<Resource name="jdbc/postgresqldb" auth="Container" type="javax.sql.DataSource"
    url="${JDBC_DATABASE_URL}"
    driverClassName="org.postgresql.Driver" initialSize="5" maxWait="5000"
    maxActive="120" maxIdle="5" validationQuery="select 1"
    poolPreparedStatements="true"/>

However, I could not make it work and have to resort to the following:

<Resource name="jdbc/postgresqldb" auth="Container" type="javax.sql.DataSource"
    username="tzse*********"  password="bea7c190************************************************"
    url="jdbc:postgresql://ec2-54-163-227-202.compute-1.amazonaws.com:5432/****************?sslmode=require"
    driverClassName="org.postgresql.Driver" initialSize="5" maxWait="5000"
    maxActive="120" maxIdle="5" validationQuery="select 1"
    poolPreparedStatements="true"/>

I basically copied and hard coded the environment variables here. This works fine, but is not portable and absolutely ugly!

Any hint where I am going wrong and what I could do to get it right ?

In Heroku console I can see:

2017-08-30T04:38:19.523960+00:00 app[web.1]: Aug 30, 2017 4:38:19 AM org.apache.naming.NamingContext lookup 2017-08-30T04:38:19.523961+00:00 app[web.1]: WARNING: Unexpected exception resolving reference 2017-08-30T04:38:19.523981+00:00 app[web.1]: java.sql.SQLException: Cannot create JDBC driver of class 'org.postgresql.Driver' for connect URL '${JDBC_DATABASE_URL}' 2017-08-30T04:38:19.523983+00:00 app[web.1]: at org.apache.tomcat.dbcp.dbcp2.BasicDataSource.createConnectionFactory(BasicDataSource.java:2160)

Does this mean that the reference to environment variables inside context.xml is not referencing the environment variables at all?

As far as I know, context.xml does not support environment variables. As an alternative, I would recommend writing the context.xml file on the fly when the app starts up. You would do this by creating a special start.sh script you use to start your app, and putting the following code in it:

#!/usr/bin/env bash

cat << EOF > context.xml
<Resource name="jdbc/postgresqldb" auth="Container" type="javax.sql.DataSource"
url="${JDBC_DATABASE_URL}"
driverClassName="org.postgresql.Driver" initialSize="5" maxWait="5000"
maxActive="120" maxIdle="5" validationQuery="select 1"
poolPreparedStatements="true"/>
EOF

java -jar yourapp.jar

Of course, you'll need to replace the java -jar yourapp.jar command with the command you use to run your app (as seen in your Procfile or heroku ps ). Then you're Procfile should contain:

web: start.sh

Because this shell script will have access to the JDBC_DATABASE_URL environment variable, the resulting context.xml file will contain the full URL.

A bit late... but although context.xml might not support environment variables (such as $JDBC_DATABASE_URL ), it DOES support Java system properties. It's possible to pass an environment variable from Heroku as a system property to your app.

Using a Procfile (which is basically a Java-command-with-prefix) and the webapp-runner :

web: java -cp "target/dependency/*" $JAVA_OPTS -DDB_URL=$JDBC_DATABASE_URL webapp.runner.launch.Main --enable-naming --port $PORT target/*.war

Here, both $JAVA_OPTS and $JDBC_DATABASE_URL are environment variables, whereas -DDB_URL will create a system property. In context.xml, use ${DB_URL} :

<Resource name="jdbc/postgresqldb" url="${DB_URL}" .../>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM