sbt-native-packager
sbt-native-packager copied to clipboard
Could not find or load main class $JAVA_OPTS
I'm deploying a Play Framework 2.5.3 application as an RPM using sbt native packager 1.2.0-M3 (using plugins PlayScala, RpmPlugin, SystemdPlugin).
I use the linux configuration mechanism as described at http://www.scala-sbt.org/sbt-native-packager/archetypes/java_server/customize.html#linux-configuration to define custom JAVA_OPTS in an /etc/default/ script:
JAVA_OPTS="-Xmx16g -Xms512m -Dpidfile.path=/var/run/myservice/play.pid -Dconfig.file=/etc/myservice/application.conf -Dlogger.file=/etc/myservice/logback.xml $JAVA_OPTS"
Starting the service using systemctl start myservice.service fails with a message
Jun 30 11:07:40 XXXXXXX myservice[29468]: Error: Could not find or load main class $JAVA_OPTS
appearing in /var/log/messages.
The problem seems to be the $JAVA_OPTS at the end, i.e. doing the following works fine:
JAVA_OPTS="-Xmx16g -Xms512m -Dpidfile.path=/var/run/myservice/play.pid -Dconfig.file=/etc/myservice/application.conf -Dlogger.file=/etc/myservice/logback.xml"
This used to work with sbt native packager 1.1.0 so I guess that this is a regression in the default script handling.
This definitely looks like a regression. The etc-default should get sourced, thus the $JAVA_OPTS should be evaluated as an environment variable.
To make sure we get this right:
- it works with
1.1.0andsystemd - does it work with
systemv? - broken with
1.2.0-M3andsystemd. Withsystemvas well?
Systemd uses the EnvironmentFile config.
Not sure how Systemd handles environment variables in this configuration. It would be interesting what's the content fo $JAVA_OPTS after you execute this line
JAVA_OPTS="-Xmx16g -Xms512m -Dpidfile.path=/var/run/myservice/play.pid -Dconfig.file=/etc/myservice/application.conf -Dlogger.file=/etc/myservice/logback.xml $JAVA_OPTS"
Before moving to 1.2.0-M3 I used 1.1.0 with systemv which worked fine. I'll try 1.2.0-M3 with systemv when I get round.
Awesome. I have a feeling the systemd and systemv behave quite differently.
When using systemd and specifying EnvironmentFile or Environment no variable substitution is taken place and variables are used as is.
From the man page for Environment section, same applies to EnvironmentFile: Variable expansion is not performed inside the strings
So, if you have JAVA_OPTS="-Dxxx=yyy $JAVA_OPTS" in your etc-default it will never work.
I'm trying to use the docker plugin from the native packager, but I think I'm running into this issue -- is it the same?
Here's a simple play app that reproduces the error for me. It's an unmodified activator play-scala app packaged in docker.
https://github.com/jsnrth/java-opts-are-broken
-j
@jsnrth Thanks for your sample project and sorry that it took so long. In your sample project the simple fix is to remove the double quotes
docker run -p 9090:9090 -e 'JAVA_OPTS=-Dhttp.port=9090' java-opts-are-broken:1.0.0
and things start to work.
Hello,
I have hit this bug, also by following the documentation for the Java Server customization.
It seems that systemd does not do variable expansion in the EnvironmentFile, as described in this stackoverflow post. So the example in the documentation where $JAVA_OPTS is used inside the environment file does not to work with systemd (I don't know about SystemV).
Perhaps the documentation should be updated?
Is there any known workaround for this, or why it is being ignored? Was it fixed in any recent releaes?