I need to run a docker image where I pass a bunch of jvm configurations to a jar file. I'm passing the configs via -e parameters as the example bellow.
Dockerfile:
FROM openjdk:9-jre
COPY test.jar /
CMD java -jar -DinstallationDate=$INSTALLATION_DATE /test.jar
Run command:
docker run -e INSTALLATION_DATE="03.05.10.2019 15:00:00" space
The problem is that when I run this, it gives me the following error:
Error: Unable to access jarfile 15:00:00
I tried running it with the json notation, like:
docker run -e ["INSTALLATION_DATE","03.05.10.2019 15:00:00"] space
It doesn't give me an error, but the parameter comes as an empty string.
I also tried to escape the space char with "\", but still didn't work.
Anyone knows how can I send this parameter to the jar execution inside the docker container? Is there another approach to this?
The problem is likely occurring because the CMD in your Dockerfile:
CMD java -jar -DinstallationDate=$INSTALLATION_DATE /test.jar
...is subject to word splitting after the variable $INSTALLATION_DATE is expanded. In order to turn off word splitting for that second argument to java, consider enclosing the variable in double quotes:
CMD java -jar -DinstallationDate="$INSTALLATION_DATE" /test.jar
Related
I'm running following command in Amazon cloud(server ec2 platform Linux ) but the terminal is throwing an error.
java -jar runnable.jar getinfo -n "kaus mond"
ERROR: Was passed main parameter 'mond"' but no main parameter was
defined.
But the same command in my local windows system is working fine.
If there is no space in "kaus mond" then working fine in Amazon cloud as well but with space not accepting.
Please suggest me how to make it work with white space.
Use single instead of double quotes around the string parameter:
java -jar runnable.jar getinfo -n 'kaus mond'
I'm trying to restart process when OOME happens. Java binary is launched using two shell scripts, one of them imports other. I don't have any control of the first one but can modify the second one as I want.
This is a prototype what I'm trying to do:
First shell script test.sh:
#!/bin/sh
JAVA_OPTS="$JAVA_OPTS -Xmx10m"
. test1.sh
echo $JAVA_OPTS
java $JAVA_OPTS $es_params TestMemory
Second shell script test1.sh:
#!/bin/sh
pidfile="test.pid"
touch $pidfile
params="$parms -Dpidfile=$pidfile"
kill_command="kill -9 \$(cat $pidfile)"
dir=$( cd $(dirname $0) ; pwd -P )
path="$dir/$(basename $0)"
start_command="$path $#"
restart_command="$kill_command;sleep 2;$start_command"
JAVA_OPTS="$JAVA_OPTS -XX:OnOutOfMemoryError=\"$restart_command\""
Generally what it does is JAVA_OPTS is constructed inside test1.sh and then used to run Java binary, which just writes PID in pidfile and then creates OOME.
Problem happens during execution, java can't understand what is a parameter and what is a class to run. I think it might be a problem of quoting, I tried different ways to escape JAVA_OPTS, but without any result. I'm either getting:
Unrecognized option: -9
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
Or
Error: Could not find or load main class "-XX:OnOutOfMemoryError=kill
If I just take a value of JAVA_OPTS and put it manually in test.sh it runs perfectly.
Any ideas how can I change test1.sh to make it work? I think I tried almost every possible way of putting double and single quotes, but without any success. Also if I put restart_command in restart.sh file and use it instead of the variable, it works fine.
After running set -x I saw that shell modifies every single space character to ' ' - adds ' on both sides. Escaping doesn't gives any result. Any idea how to avoid this? So final commend is:
+ java -Xmx10m '"-XX:OnOutOfMemoryError=kill' '$(cat' 'test.pid);sleep' '2;/Users/davidt/test/TestMemory/bin/test.sh' '")' -Des.pidfile=test.pid TestMemory
Update
I can run simplified command successfully
java "-XX:OnOutOfMemoryError=echo 'Ups'" $es_params TestMemory
But it seems a general problem, shell just hates spaces into variables I guess:
JAVA_OPTS="\"-XX:OnOutOfMemoryError=echo 'Ups'\""
set -x
java $JAVA_OPTS TestMemory
This script fails and the last line is interpreted as:
java '"-XX:OnOutOfMemoryError=echo' ''\''Ups'\''"' TestMemory
I tried different options to escape
This is a shell problem. Based on the evidence, I'd say that one of the ; characters ... and possibly some why space ... is being interpretted by the shell when you don't want / need this to happen.
If you run set -x in the shell before running the command that is trying to start the JVM, you will see the actual command that is being used.
It seems shell translates every single space to ' ',
Not exactly. The single quotes are inserted by the shell into the output you are getting from set -x. They simply indicating where the argument boundaries are. They are not really there ... and they are certainly NOT being passed to the java command.
Any idea how to [a]void it?
What you need to do is start from the (final) command that you are trying execute ...
java -Xmx10m -XX:OnOutOfMemoryError="kill NNNN;sleep 2;/Users/davidt/test/TestMemory/bin/test.sh" -Des.pidfile=test.pid TestMemory
... and work backwards, so that the shell variables, expansions and escaping give you what you need.
The other thing to note is that this:
java -Xmx10m -XX:OnOutOfMemoryError="kill $(cat test.pid); ..."
probably won't work. The kill $(cat test.pid) command is using shell syntax and requires shell functionality to interpolate the contents of the PID file. I doubt that the JVM is going to know what to do with that. (Or more accurately. It will do what you have literally told it to do, but that will not be what you want ...)
If you really need to interpolate the pid file content when the restart command is run as you appear to be trying to do, then suggest that turn the restart command into a free-standing shell script, and set the file mode so that it is executable. It will be simpler and a lot easier to get working.
As a general piece of advice, is is a bad idea to be too clever with shell scripts. The exact semantics of variable expansion and command parsing are rather tricky, and it is easy to get yourself really confused ... if you are trying to do this at multiple levels.
I ended up put the script I wanted to execute in a separate file and gave it as a parameter to JVM to execute when OOME happens.
echo "echo 'UPS'" >> oome_happened.sh
JAVA_OPTS="\"-XX:OnOutOfMemoryError='oome_happened.sh'\""
set -x
java $JAVA_OPTS TestMemory
Like #DaTval said, you should put the command in a script. The script should be someting like.
#!/bin/bash
kill -9 $PPID
Kill the caller of scripts.
I've searched throughout this site and tried a few solutions when receiving this message but nothing seems to work.
I am trying to invoke a shell script on Ubuntu 12.04.2 (with java-7-openjdk-amd64) that runs a java program and then I get a "Error: Could not find or load main class com.xx" error.
This is how my script invokes Java:
"$JAVA" $server_jvmargs $javaProps -Dxx.home="$XX_HOME" -Duser.dir="$XX_HOME" -cp $client_classpath $mainclass $args
And the arguments you see above are defined as follows:
args=$*
javaProps=
mainclass=com.xx
server_jvmargs="-Djava.awt.headless=true -Xms1024m -Xmx1024m $jvmargs"
XX_HOME="`pwd`/../.."
client_classpath="$XX_HOME/lib/client/patch.jar;$XX_HOME/lib/client/xyx-xxx.jar;$clientlibs;$XX_HOME/lib/server/standard-1.1.2.jar;$publictilesource;$respath;$XX_HOME/lib/client/xxmainclass.jar"
The mainclass variable is in the classpath located in the xxmainclass.jar file so I'm not sure as to why it cannot find it?
Does anyone have any ideas on what could be going on?
To see what actually happens when you run your script, invoke it with bash -x, or put set -x at the top; this will print each command before it's run, so you can see how it's actually starting the JVM. Without this information, it's hard to come up with a better diagnosis. That said...
You've been copying off Tomcat's startup scripts, it looks like. Don't; they're awful.
Something a little more correct on the shell side might look like this:
args=( "$#" )
javaProps=( )
mainclass=com.xx
server_jvmargs=( -Djava.awt.headless=true -Xms1024m -Xmx1024m "${jvmargs[#]}" )
XX_HOME="$PWD/../.."
client_classpath="$XX_HOME/lib/client/patch.jar:$XX_HOME/lib/client/xyx-xxx.jar:$clientlibs:$XX_HOME/lib/server/standard-1.1.2.jar:$publictilesource:$respath:$XX_HOME/lib/client/xxmainclass.jar"
java \
"${server_jvmargs[#]}" \
"${javaProps[#]}" \
-Dxx.home="$XX_HOME" \
-Duser.dir="$XX_HOME" \
-cp "$client_classpath" \
"$mainclass" "${args[#]}"
The use of ${foo[#]} expands the array foo with literal contents. Note that foo must be created as an array in this case, and you need to be using a shell that supports arrays (so your script needs to start with #!/bin/bash, not #!/bin/sh).
See http://mywiki.wooledge.org/BashFAQ/005 for an introduction to arrays in bash.
use a : instead of a ; in your classpath.
unix just rolls that way.
Try this:
Java -jar pathToYOurFile.jar
Please check if line end character is OS specific in your shell script
I'm complete Linux newbie, but still want to provide a simple way for Linux users to start my Java program.
Therefore I want to create a shellscript.
I can't test my script so I'll have to ask here if this is working correctly:
#!/bin/bash
java -cp "bin";"extres/junit.jar" data.ProgramOne
exit 0
Your mistake is in path delimiter. It is ; on Windows and : on Linux.
Moreover you should not wrap each classpath fragment with "". On unix you can escape spaces and other forbidden characters using \. So, I'd re-write the java execution line as:
java -cp bin:extres/junit.jar data.ProgramOne
This will run when you are executing script from your app directory where you have subdirectory bin and extres.
try this:
java -cp "bin:extres/junit.jar" data.ProgramOne
Java under Unixes uses : as the separator in the classpath, so you'd need (the quotes are not necessary):
#!/bin/bash
java -cp bin:extres/junit.jar data.ProgramOne
If I run
which java
from the command line I get the proper input (/usr/java/.../bin/java). However if I run it in a php script:
<?
echo 'java. ' . shell_exec('which java');
echo 'ls. ' . shell_exec('which ls');
?>
nothing gets printed out for which java but I get the proper results for which ls...
Two things were needed:
the full path to the JVM (it wasn't set in the environment)
" 2>&1" at the end of the command line.
So for example:
echo shell_exec('/usr/java/jdk6/bin/java -cp myJars.jar MyMainClass arg1 2>&1");
I just ran into this problem as well. I was trying to determine if the qrencode utility is installed on the (any) server, and if not then log/warn/exit gracefully.
Considering the program should always be in a standard path, I prefixed the which command with the likely locations of the binary, while still respecting that $PATH might be somehow defined on the system. I think you could use this approach with common Java paths, too:
shell_exec('PATH="$PATH:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin" '.
'which qrencode');