tags:

views:

167

answers:

5

I've been experiencing a strange issue the last couple of days while writing a shell script which executes Java (starting the JBoss AS). I have a variable JAVA_OPTS that I am creating, and finally passing to the 'java' command. When I hard code the values in JAVA_OPTS rather than using variable expansion, the java process executes normally. When I use variable expansion, I get errors from the java executable. Here is the relevant portions of the script:

SERVER="-server"
MEM_OPTS="-Xms512m -Xmx1024m"

case "$1" in
start)
    java "$SERVER" "$MEM_OPTS" $JAVA_OPTS \
    -classpath "${JBOSS_CLASSPATH}" \
    -Dorg.jboss.resolver.warning=true \
    -Dsun.rmi.dgc.client.gcInterval=3600000 \
    -Dsun.rmi.dgc.server.gcInterval=3600000 \
    -Djboss.server.name=${SERVICE_NAME} \
    -Djboss.server.base.dir=`dirname ${EC_APP_HOME}` \
    -Djboss.server.base.url=file://`dirname ${EC_APP_HOME}` \
    -Djboss.server.home.dir=${EC_APP_HOME} \
    -Djboss.server.home.url=file://${EC_APP_HOME} \
    org.jboss.Main >> out.log 2>&1 &

Executing this gives the following:

Invalid initial heap size: -Xms512m -Xmx1024m
Could not create the Java virtual machine.

However when I remove the variable expansion like so:

    java "$SERVER" -Xms512m -Xmx1024m $JAVA_OPTS \

java executes no problems. As an aside, when I include "-server" in the MEM_OPTS var, I get the error "unrecognized option".

So obviously, there is something up with the variable expansion. I've hexdump'd the script, and made sure there are no extra characters in the string, and verified that I'm using Unix line endings. I've also reproduced the problem on two different linux machines, albeit both running the same version of ubuntu (one 32bit, the other 64bit).

EDIT: I get the same result with all forms of variable substitution: $MEM_OPTS, ${MEM_OPTS}, "${MEM_OPTS}"

Any ideas?

+5  A: 

When you use "$MEM_OPTS", you're passing -Xms512m -Xmx1024m as a single option.

Try this instead:

java "$SERVER" $MEM_OPTS $JAVA_OPTS \

A good guide to variable substitution and quoting with examples: http://tldp.org/LDP/abs/html/varsubn.html

ZoogieZork
Thanks for responding. I get the same result without quotes as well. I updated the original question clarifying this.
purecharger
+2  A: 

I am not 100% sure about the semantics of the quotes, but "$MEM_OPTS" may create a single argument "-Xms512m -Xmx1024m", whereas the JVM needs to see two seperate arguments. Can you try without the quotes?

java $SERVER $MEM_OPTS $JAVA_OPTS 
Thilo
+2  A: 

think it should work if the quotes around $MEM_OPTS are removed, as the quotes tell bash to pass the expanded contents as a single token argument to execv()

jspcal
+1  A: 

It should be a simple matter of changing:

java "$SERVER" "$MEM_OPTS" $JAVA_OPTS \

to:

java "$SERVER" $MEM_OPTS $JAVA_OPTS \

so that the memory options are passed as two arguments.

But, since you say that doesn't work (?), please try the following.

A) Create a shell script fakejava.sh containing:

#!/usr/bin/bash
echo $#
while [[ $# -ne 0 ]] ; do
    echo "    [$1]"
done

(you may need to alter that first line if your bash is somewhere else: use which bash to figure out where).

B) Set its permissions correctly:

chmod 700 fakejava.sh

C) Replace your entire java command with:

./fakejava.sh "$SERVER" $MEM_OPTS $JAVA_OPTS xx

and see how many arguments there actually are. I get:

5
    [-server]
    [-arg1]
    [-arg2]
    [none]
    [xx]

from the controlling script:

#!/usr/bin/bash
JAVA_OPTS="none"
SERVER="-server"
MEM_OPTS="-arg1 -arg2"
./fakejava.sh "$SERVER" $MEM_OPTS $JAVA_OPTS xx
paxdiablo
I figured out my mistake - not resetting the IFS variable. This test would have helped show this. Thanks!
purecharger
@purecharger, you should probably accept your own answer (since that's the actual fix) and vote up _all_ of those that helped. You'll have to wait 24 hours before accepting your own answer, I think. Cheers, and glad you got it sorted out.
paxdiablo
Yup, need 10 more hours. Thank you!
purecharger
+2  A: 

My mistake - I was setting IFS to "\n" only in a script I sourced in, functions.sh. I was never resetting the IFS to "\n\t ", so the variables were not split on spaces.

Thanks for the responses!

purecharger
+1 since this is the "actual" solution, even though the others were helpful.
paxdiablo