sbt / sbt-native-packager

sbt Native Packager
https://sbt-native-packager.readthedocs.io/en/stable/
BSD 2-Clause "Simplified" License
1.6k stars 442 forks source link

Could not find or load main class $JAVA_OPTS #832

Open martinstuder opened 8 years ago

martinstuder commented 8 years ago

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.

muuki88 commented 8 years ago

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:

muuki88 commented 8 years ago

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"
martinstuder commented 8 years ago

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.

muuki88 commented 8 years ago

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

kwark commented 8 years ago

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.

jsnrth commented 8 years ago

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

muuki88 commented 7 years ago

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

nfsantos commented 6 years ago

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?

javolek commented 1 year ago

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