Solaris/UNIX passing "$*" to compiled java - java

I am having a strange issue with passing "$*" to a java compiled program. The program will not parse the variables when I pass it from the following command line:
/export/home/checkout>/tmp/jsnmp.sh -f noc2 -t 4,4 -x \"resdiag SilentDiag 1\",18
The "/tmp/jsnmp.sh" contains the following:
#!/bin/sh
$JAVA_HOME/bin/java -jar /export/home/checkout/jsnmp.jar $*
Now if I run this:
$JAVA_HOME/bin/java -jar /export/home/checkout/jsnmp.jar \
-f noc2 -t 4,4 -x "resdiag SilentDiag 1",18
Everything works.
Any ideas folks?

You probably want to maintain the quoting within the script, so use "$#".

This has nothing to do with Java or Solaris, this is purely shell stuff.
This is because after $* substitution arguments will get re-parsed and will become separate arguments. E.g. your java executable will see it as
-f noc2 -t 4,4 -x resdiag SilentDiag 1,18
or something like that.
Check out the following test code:
a.sh:
echo $1
echo $2
echo $3
./b.sh $*
b.sh:
echo b
echo $1
echo $2
echo $3
Running it will produce the following output:
$ ./a.sh "1 2" 3
1 2
3
b
1
2
3
See how it was 2 arguments for the first script and 3 params for the second.
Encompassing $* in double quotes won't help, because it will send all arguments as one argument.
The following should work:
#!/bin/sh
$JAVA_HOME/bin/java -jar /export/home/checkout/jsnmp.jar "$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9"
You will have some max number of arguments though...

Related

can't make a shell script to make a jar file

I try to make a simple shell script to make a jar file. The jar command combined with -C does not work with wildcards. Therefor I use a wildcard to find the files I want. Write them to a file, and loop over them.
It looks something like this:
the_classes=''
cd "$bin_folder"
tmp_dir=$(mktemp -d -t java_sucks)
find "imui/core/" -type f -name "IMUI_Widget_Agent*.class" >"$tmp_dir/classes.txt"
while IFS="" read -r p || [ -n "$p" ]
do
the_classes="${the_classes} -C '$bin_folder' '$p'"
done < "$tmp_dir/classes.txt"
Using the above I complete the command:
cmd='jar cfm build/IMUI_Widget_Agent.jar'
cmd="${cmd} \"$bin_folder/imui/core/IMUI_Widget_Agent_MANIFEST.MF\" $the_classes"
printf "\n\n\ncmd\n\n\n"
echo $cmd
Now if I copy and paste this command to execute it works!
But I want to avoid the manual labour of doing the copy and paste by hand every time.
Now I have:
eval "$("$cmd")"
But I get an error File name too long. No matter what I try, every fix I do creates a new problem. I have been working 6 hours now to make this script.
What would be a good step forward?
Since you cd "$bin_folder" you don't actually need -C "$bin_folder":
#!/bin/bash
shopt -s globstar
cd "$bin_folder"
jar cfm build/IMUI_Widget_Agent.jar \
imui/core/IMUI_Widget_Agent_MANIFEST.MF \
imui/core/**/IMUI_Widget_Agent*.class
However, if you still want to add them as part of a larger script, you can easily and robustly build your command in an array:
#!/bin/bash
shopt -s globstar
cmd=(jar cfm build/IMUI_Widget_Agent.jar imui/core/IMUI_Widget_Agent_MANIFEST.MF)
cd "$bin_folder"
for file in imui/core/**/IMUI_Widget_Agent*.class
do
cmd+=(-C "$bin_folder" "$file")
done
echo "About to execute: "
printf "%q " "${cmd[#]}"
echo
"${cmd[#]}"
Alternatively, you can simply do eval "$cmd" with your code, which is equivalent to echo and copy-pasting. However, be aware that this is fragile and error prone because it requires careful escaping of the filenames which you're not currently doing.

How to get arguments from console in java when using a bash file?

I have a java project that I launch using a bash file :
#!/usr/bin/env bash
java -classpath logger/bin:banking/bin:testframework/bin test.RunTest
I launch my bash in my terminal (in ubuntu) :
firefrost#firefrost-PC:~/ProjetPOO3A$ bash test.sh banking.Account
In my main, I try to get arguments as :
public class RunTest {
public static void main(String[] args) {
System.out.println(args.length);
for(int i = 0; i < args.length; i++)
{
...
The problem is that args.length is 0 when it should be 1 because I passed the argument "banking.Account" in my console.
If I put the argument in the bash file :
#!/usr/bin/env bash
java -classpath logger/bin:banking/bin:testframework/bin test.RunTest banking.Account
my main recognize the argument and the System.out.println outputs 1.
Why is the argument in the console not taken into account?
There is no problem in Java code. Your parameters are not propagated to java command in shell script.
#!/usr/bin/env bash
java -classpath logger/bin:banking/bin:testframework/bin test.RunTest "$#"
The $# variable contains all parameters passed to shell script.
Command line arguments to a bash script can be accessed with $1, $2, etc. Here's a fuller explanation.
Try updating your script as follows:
#!/usr/bin/env bash
java -classpath logger/bin:banking/bin:testframework/bin test.RunTest $1
You forget to process the argument in the bash file.
You can access them by using $1, $2, $3, $... variables.
For example writing ./my.sh test test2 $1 will contain test and $2 test2
So change your script to
#!/usr/bin/env bash
java -classpath logger/bin:banking/bin:testframework/bin test.RunTest $1
Add "$#" to pass the arguments to the program:
#!/bin/bash
java -classpath logger/bin:banking/bin:testframework/bin test.RunTest "$#"
Don't forget the quotes around $# so bash will "protect" each argument:
#
Expands to the positional parameters, starting from one. When the
expansion occurs within double quotes, each parameter expands to a
separate word. That is, "$#" is equivalent to "$1" "$2" ... If the
double-quoted expansion occurs within a word, the expansion of the
first parameter is joined with the beginning part of the original
word, and the expansion of the last parameter is joined with the last
part of the original word. When there are no positional parameters,
"$#" and $# expand to nothing (i.e., they are removed).
See bash man.

Pass parameters to bash file in the middle of a java code

I have a Java code running by the following command line
java -jar CPM-1.0-SNAPSHOT-jar-with-dependencies.jar Example arg[0] arg[1] arg[2] arg[3]
clearly I need to pass 4 parameters.
In the middle of my Java code, I should call a C++ code using the following bash file.
#!/bin/bash
/home/CPM/Codes/source/GcEqClass arg[0]
arg[0] in the bash file is same as arg[0] in Java command line and the main reason to have arg[0] in command line is to use it in bash script. My question, how can I pass arg[0] from the command line to the bash script without editing the bash file manually?
Your bash file should be:
#!/bin/bash
/home/CPM/Codes/source/GcEqClass "$#"
"$#" is basically equivalent to the the argument array in java, and similar to "$1" "$2" "$3" ..
From Java, you can then do:
Runtime.getRuntime().exec(new String[] {
"/yourpath/toyour/script", arg[0]
});
write the script:
#!/bin/bash
java -jar CPM-1.0-SNAPSHOT-jar-with-dependencies.jar Example $1 $2 $3 $4
save it as say scritp.sh, then run it :
./script.sh 1 2 3 4

Calling java program dependent on external library

I am trying to call a java program in php to use it with web interface.
Java program is dependent on an external lib: commons-cli-1.2.jar
So basically I need to export it before calling the java program; but if I export it first as:
shell_exec('export CLASSPATH=$CLASSPATH:~/lib/commons-cli-1.2.jar');
then call the java program as:
shell_exec('java ComputePagerank -i $para_i -d $para_d -e $para_e -o $para_o');
I think it creates different shells for each call; then the export does not have any effect on java program. Or am I wrong?
Otherwise, it should output a file in the server. But simply it does not. So, what is wrong? Any idea?
edit: However can it be because some parameters such as para_i stands for an input file name, so that i have to specify full path for that? Because I just assume if the input file is in the same working directory, there won't be any problem, will it?
edit-2: it outputs properly when i use command line;)
you're right, each shell_exec creates a separate shell.
env CLASSPATH=whatever java -switches
I would use
shell_exec('java -cp $CLASSPATH:/home/yourname/dir/lib/commons-cli-1.2.jar ComputePagerank -i $para_i -d $para_d -e $para_e -o $para_o > message');
and (this is important) replace the tilde(~) with the actual path to your directory (/home/yourname say). The ~ is expanded by the shell and is dependent on which shell you''re using.
Try Creating a simple shell script with the commands that you want to execute. You may pass arguments to a shell script so that is not a problem either.
for example
echo "Running Script..."
java -cp $CLASSPATH:~/lib/commons-cli-1.2.jar ComputePagerank -i $1 -d $2 -e $3 -o $4 > message
etc.
Then try calling it from the command line first with some parameters. Did it output? Then try calling it from the php script. Did it output? If it did not then you may need to check permissions. I had a simiolar experience some time ago with a Java program that simply did not have permission to write a file.
You should be able to call it like this.
shell_exec('java -cp $CLASSPATH:~/lib/commons-cli-1.2.jar ComputePagerank -i $para_i -d $para_d -e $para_e -o $para_o > message');
Another option is to issue the 2 commands seperately, but to the same shell, like this:
shell_exec('export CLASSPATH=$CLASSPATH:~/lib/commons-cli-1.2.jar; java ComputePagerank -i $para_i -d $para_d -e $para_e -o $para_o > message');
edit:
some shells don't let you call export while you're setting up the variable. so this may be safer than the second option above:
shell_exec('CLASSPATH=$CLASSPATH:~/lib/commons-cli-1.2.jar; export CLASSPATH; java ComputePagerank -i $para_i -d $para_d -e $para_e -o $para_o > message');
another edit:
If none of the above work then you're going to have to do some more trouble shooting. Does your java program work from the command prompt?
java -cp $CLASSPATH:/home/user/lib/commons-cli-1.2.jar ComputePagerank -i param1 -d param2 -e param3 -o param4 > message

Bash variable expansion causes Java commandline to break

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?
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
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
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()
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!
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

Categories

Resources