3

I'm using OpenShift, and I'm trying to deploy my application to a local Tomcat instance for faster development. I'm using EclipseLink for DB transactions, and I've provided the environment variables OpenShift uses in persistence.xml like this:

<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/> 
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://${env.OPENSHIFT_MYSQL_DB_HOST}:${env.OPENSHIFT_MYSQL_DB_PORT}/mydbname"/> 
<property name="javax.persistence.jdbc.user" value="${env.OPENSHIFT_MYSQL_DB_USERNAME}"/> 
<property name="javax.persistence.jdbc.password" value="${env.OPENSHIFT_MYSQL_DB_PASSWORD}"/>

I'm using linux on my local machine, so I've set all of these variable values to the local versions as well (localhost, 3306, etc). I've double checked that they are available in terminal. I've also tried providing them like described here - I've opened the Tomcat instance's settings in Eclipse, chose "Open launch configuration", and on the Arguments tab, I've typed them into VM arguments (also tried the "Variables..." menu). However, it's not working, and I'm getting NumberFormatException on the PORT variable, I guess it takes the raw string "${env.OPENSHIFT_MYSQL_DB_PORT}" as port.

(Apparently, it's not working on OpenShift either.)

Where can I set these variable values in Eclipse/Tomcat to make it work?

Thank you in advance!

Community
  • 1
  • 1
Peter
  • 323
  • 1
  • 16
  • 46

4 Answers4

13

In WildFly the simples and most elegant way to do that is enabling the property replacement in the ee subsystem, as in the following example:

<subsystem xmlns="urn:jboss:domain:ee:4.0">
      <spec-descriptor-property-replacement>true</spec-descriptor-property-replacement>
      <jboss-descriptor-property-replacement>true</jboss-descriptor-property-replacement> 
. . .
</subsystem>

Now you can use the BeanShell expression with the env prefix to reference environment variables. For example:

<property name="javax.persistence.jdbc.url" value="jdbc:mysql://${env.MYSQL_DB_HOST}:${env.MYSQL_DB_PORT}/mydbname"/> 
<property name="javax.persistence.jdbc.user" value="${env.MYSQL_DB_USERNAME}"/> 
<property name="javax.persistence.jdbc.password" value="${env.MYSQL_DB_PASSWORD}"/>

This strategy is particularly useful in cloud environment such as Openshift, where you can pass environment variables to your Applications, in order to customize them.

frekele
  • 644
  • 6
  • 13
  • Not sure why, but this didnt work for me, it tried to connect to the database as user `${env.MYSQL_DB_USERNAME}` – JGlass Dec 18 '20 at 17:32
1

This is not possible. If you are using spring this can be possible there, but for simple JPA no. What you can do though is to use programmatic configuration and to do something like this described in this post Read Environment Variables in persistence.xml file

Community
  • 1
  • 1
Alexander Petrov
  • 9,204
  • 31
  • 70
1

For testing purposes or in the JavaSE world, you could use this full working eclipseLink example.

It gets all properties defined in the persistence.xml from the PersistenceUnitInfo instance which is obtained from the EntityManagerFactory (by using eclipseLink specific implementations). These properties get replaced with the values defined in environment variables.

baumato
  • 358
  • 3
  • 13
1

I am using a simple maven jpa project.

You can do that with a simple bash script and using a template file

template

template content:

...
<property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver"/>
<property name="javax.persistence.jdbc.url" value="$DB_URL"/>
<property name="javax.persistence.jdbc.user" value="$DB_USR"/>
<property name="javax.persistence.jdbc.password" value="$DB_PASS"/>
...

bash script:

XML_TMP=./src/main/resources/META-INF/persistence.temp.xml
XML_OUT=./src/main/resources/META-INF/persistence.xml

export DB_URL="jdbc:postgresql://localhost:5434/my_db"
export DB_USR="admin"
export DB_PASS="mystrongpass"

envsubst "`printf '${%s} ' $(sh -c "env|cut -d'=' -f1")`" < $XML_TMP > $XML_OUT

Note that env var can be system values too, you do not necessarily have to be included in the file

run the script and then just do:

mvn clean package
Adán Escobar
  • 1,729
  • 9
  • 15