sbt-native-packager icon indicating copy to clipboard operation
sbt-native-packager copied to clipboard

Could not find or load main class $JAVA_OPTS

Open martinstuder opened this issue 9 years ago • 9 comments

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.

martinstuder avatar Jun 30 '16 10:06 martinstuder

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.0 and systemd
  • does it work with systemv?
  • broken with 1.2.0-M3 and systemd. With systemv as well?

muuki88 avatar Jul 01 '16 08:07 muuki88

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"

muuki88 avatar Jul 01 '16 08:07 muuki88

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.

martinstuder avatar Jul 04 '16 08:07 martinstuder

Awesome. I have a feeling the systemd and systemv behave quite differently.

muuki88 avatar Jul 04 '16 10:07 muuki88

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.

kwark avatar Oct 20 '16 12:10 kwark

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 avatar Nov 15 '16 18:11 jsnrth

@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.

muuki88 avatar May 28 '17 20:05 muuki88

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?

nfsantos avatar Dec 18 '17 16:12 nfsantos

Is there any known workaround for this, or why it is being ignored? Was it fixed in any recent releaes?

javolek avatar Sep 15 '23 15:09 javolek