Perl system call to jar file failing in cron - java

I am trying to execute a perl script via a cron job that uses the system command to execute a java wrapper for boilerpipe. It fails when executed via cron. The script (simplified) is
my $link = "http://foo.bar"; # with a real link
my $cmdstring = 'java -jar boilerpipe-wrapper.jar url '.$link.' out.txt';
my $result = system($cmdstring);
if ($? == -1) {
print LOG "failed to execute system command: $!\n";
die;
}
elsif ($? & 127) {
printf LOG "child died with signal %d, %s coredump\n",
($? & 127), ($? & 128) ? 'with' : 'without';
die;
}
else {
printf LOG "child exited with value %d\n", $? >> 8;
die;
}
The die commands are in there for debugging purposes. What appears in LOG is
child exited with value 1
The crontab line is
24 7 * * * perl /home/retrievetext.pl >> /home/cron-msgs 2>&1
What appears in cron-msgs is
Error: unable to access jarfile boilerpipe-wrapper.jar
Died at /home/retrievetext.pl line 15
The ls -la for boilerpipe-wrapper.jar is
-rwxr-xr-x 1 steve sudo 1945275 Apr 29 03:53 boilerpipe-wrapper.jar
The Perl script and the system call work as expected when executed from the terminal. Anyone know what the problem is?

Related

shell script error : [: : integer expression expected

i am trying to trigger an email alert based on the java script output but i am getting an error like below in the shell script,
script.sh: line 22: [: : integer expression expected
Below is my shell script format,
out="$(java -jar /waitrose/scripts/OF/BOBIErrorAutomation/BOBIAutomation.jar
2>&1)"
if [ "$out" -gt 0 ]
then
mail -s "script did not completed successfully" $mailid_list
exit 0
fi
Below is the sample error returned by the java program :
The error was: com.ibm.db2.jcc.c.a.<init>(a.java:174) 174
com.ibm.db2.jcc.c.b.a(b.java:1745) 1745
com.ibm.db2.jcc.b.p.<init>(p.java:934) 934
Can anyone tell me how to capture the output from the java program and trigger the mail in shell ?
are you not comparing the output of your java program which in the case where it crashes, most likely going to be a string of some sort, against (-gt greater than) an integer? the comparator expects a whole number, not a crash message from java.
EDIT: ill elaborate, perhaps it would be better to test if $out is an integer first, if your jar only outputs integers if it runs correctly:
if ! [[ "$out" =~ ^[0-9]+$ ]]
then use this to trigger your mail, and else to normal functionality.

WEKA quote parse error

While using java "setOptions" function with the bellow properties I am getting an error : "Quote parse error."...
"weka.classifiers.meta.OneClassClassifier -num \"weka.classifiers.meta.generators.GaussianGenerator -S 1 -M 0.0 -SD 1.0\" -nom \"weka.classifiers.meta.generators.NominalGenerator -S 1\" -trr 0.1 -tcl F&B -cvr 10 -cvf 10.0 -P 0.5 -S 1 -W weka.classifiers.meta.Bagging -- -P 100 -S 1 -num-slots 1 -I 10 -W weka.classifiers.trees.REPTree -- -M 2 -V 0.001 -N 3 -S 1 -L -1 -I 0.0"
I understand that this is occurring because of error in applying quotes, but I am not sure as to where they should be applied.
I thought of applying them before calling REPTree but that doesn't seem to work.
Whenever using a Weka classifier with Java code, use the weka.core.Utils.splitOptions method to parse the config string without worrying about quoting and escaping characters.
// set your configurations parameters here, e.g., "-S 1"
String options = "whatever configuration you want";
// instantiate the classifier object
REPTree tree = new REPTree();
// parse and set the classifier's configuration
tree.setOptions(Utils.splitOptions(options));
Also, remember to provide your current code and to format your question.

Android jar/dex method count on windows

I've seen some links for counting the methods on Linux and MacOS, but I haven't seen anything for Windows. How do you count a number of methods in a .dex or .jar file?
After unsuccessful search for a solution, I wrote two simple batch/shell scripts that do that.
The first one, methodcount.bat, checks if the file is .dex or .jar, and if it's a .jar file, it processes it with dx into dex file and then calls the second one, printhex.ps1, that actually checks the number of methods in the dex file - it reads 2 bytes beginning at 88 (little endian) and converts them into a decimal number.
To use this you to have dx somewhere in your path (it's in the android SDK build-tools/xx.x.x folder) and have PowerShell installed (it should already be installed on Windows 7/8).
Usage is very simple: methodcount.bat filename.dex|filename.jar.
Here are the scripts, but you can also find them on gist: https://gist.github.com/mrsasha/9f24e129ced1b1db791b.
methodcount.bat
#ECHO OFF
IF "%1"=="" GOTO MissingFileNameError
IF EXIST "%1" (GOTO ContinueProcessing) ELSE (GOTO FileDoesntExist)
:ContinueProcessing
set FileNameToProcess=%1
set FileNameForDx=%~n1.dex
IF "%~x1"==".dex" GOTO ProcessWithPowerShell
REM preprocess Jar with dx
IF "%~x1"==".jar" (
ECHO Processing Jar %FileNameToProcess% with DX!
CALL dx --dex --output=%FileNameForDx% %FileNameToProcess%
set FileNameToProcess=%FileNameForDx%
IF ERRORLEVEL 1 GOTO DxProcessingError
)
:ProcessWithPowerShell
ECHO Counting methods in DEX file %FileNameToProcess%
CALL powershell -noexit -executionpolicy bypass "& ".\printhex.ps1" %FileNameToProcess%
GOTO End
:MissingFileNameError
#ECHO Missing filename for processing
GOTO End
:DxProcessingError
#ECHO Error processing file %1% with dx!
GOTO End
:FileDoesntExist
#ECHO File %1% doesn't exist!
GOTO End
:End
printhex.ps1
<#
.SYNOPSIS
Outputs the number of methods in a dex file.
.PARAMETER Path
Specifies the path to a file. Wildcards are not permitted.
#>
param(
[parameter(Position=0,Mandatory=$TRUE)]
[String] $Path
)
if ( -not (test-path -literalpath $Path) ) {
write-error "Path '$Path' not found." -category ObjectNotFound
exit
}
$item = get-item -literalpath $Path -force
if ( -not ($? -and ($item -is [System.IO.FileInfo])) ) {
write-error "'$Path' is not a file in the file system." -category InvalidType
exit
}
if ( $item.Length -gt [UInt32]::MaxValue ) {
write-error "'$Path' is too large." -category OpenError
exit
}
$stream = [System.IO.File]::OpenRead($item.FullName)
$buffer = new-object Byte[] 2
$stream.Position = 88
$bytesread = $stream.Read($buffer, 0, 2)
$output = $buffer[0..1]
#("{1:X2} {0:X2}") -f $output
$outputdec = $buffer[1]*256 + $buffer[0]
"Number of methods is " + $outputdec
$stream.Close()
I see this question is old, but there's a Gradle plugin that will work on Windows which will report the method-reference count in an APK on each build: https://github.com/KeepSafe/dexcount-gradle-plugin.

Launching JRE in Linux from a FAT32 USB

I have a Java application installed on a USB which the user should be able to run from any OS.
For this,
I'm packaging a JRE instance on the USB along with my application.
I'm having a FAT32 file-system on the USB.
However, the problem is, FAT32 has no concept of execute ("+x") permissions. While I can launch a shell script, like so:
$ sh /path/to/fat32-usb/helloWorld.sh
, and while I can launch a simple ELF binary, like so:
$ /lib64/ld-linux-x86-64.so.2 /path/to/fat32-usb/helloWorld
, I can't seem to be able to launch the Java ELF program. I get these errors:
Error: could not find libjava.so
Error: Could not find Java SE Runtime Environment.
Before launching java, I've tried setting these environment variables as follows:
export JAVA_HOME=/path/to/fat32-usb/jre
export LD_LIBRARY_PATH="$JAVA_HOME/lib/amd64:.:$LD_LIBRARY_PATH"
export PATH="$JAVA_HOME/bin:.:$PATH"
I have also tried launching java from inside the $JAVA_HOME/bin directory. Finally, I've also tried copying all the libXXX.so's from $JAVA_HOME/lib/amd64/ to $JAVA_HOME/bin, hoping that they would get picked up from the current directory, ., somehow.
But nothing has worked.
EDIT
Here are the last few lines of strace output:
$ strace -vfo /tmp/java.strace /lib64/ld-linux-x86-64.so.2 /path/to/fat32-usb/jre ...
...
readlink("/proc/self/exe", "/lib/x86_64-linux-gnu/ld-2.17.so", 4096) = 32
write(2, "Error: could not find libjava.so", 32) = 32
write(2, "\n", 1) = 1
write(2, "Error: Could not find Java SE Ru"..., 50) = 50
write(2, "\n", 1) = 1
exit_group(2) = ?
EDIT2
And here is the output of ltrace (just a single line!):
$ ltrace -s 120 -e '*' -ifo /tmp/java.ltrace /lib64/ld-linux-x86-64.so.2 /path/to/fat32-usb/jre ...
30913 [0xffffffffffffffff] +++ exited (status 2) +++
EDIT 3
This is ltrace excerpt around loading of libjava.so by a Java on an ext4 partition (and not the problem FAT32 partition), which I can load fine:
5525 [0x7f7627600763] <... snprintf resumed> "/home/aaa/bbb/jdk1.7.0_40/lib/amd64/libjava.so", 4096, "%s/lib/%s/libjava.so", "/home/aaa/bbb/jdk1.7.0_40", "amd64") = 46
5525 [0x7f762760076d] libjli.so->access("/home/aaa/bbb/jdk1.7.0_40/lib/amd64/libjava.so", 0) = -1
5525 [0x7f762760078d] libjli.so->snprintf( <unfinished ...>
5525 [0x3085246bdb] libc.so.6->(0, 0x7fffffd8, 0x7f7627607363, 39) = 0
5525 [0x3085246be3] libc.so.6->(0, 0x7fffffd8, 0x7f7627607363, 39) = 0
5525 [0x7f762760078d] <... snprintf resumed> "/home/aaa/bbb/jdk1.7.0_40/jre/lib/amd64/libjava.so", 4096, "%s/jre/lib/%s/libjava.so", "/home/aaa/bbb/jdk1.7.0_40", "amd64") = 50
5525 [0x7f7627600797] libjli.so->access("/home/aaa/bbb/jdk1.7.0_40/jre/lib/amd64/libjava.so", 0) = 0
And this is the strace output of, again, the healthy/loading java.
5952 readlink("/proc/self/exe", "/home/aaa/bbb/jdk1.7.0_40/bin/ja"..., 4096) = 34
5952 access("/home/aaa/bbb/jdk1.7.0_40/lib/amd64/libjava.so", F_OK) = -1 ENOENT (No such file or directory)
5952 access("/home/aaa/bbb/jdk1.7.0_40/jre/lib/amd64/libjava.so", F_OK) = 0
5952 open("/home/aaa/bbb/jdk1.7.0_40/jre/lib/amd64/jvm.cfg", O_RDONLY) = 3

System.exit return code isn't detected by bash eval

struggling with this for an hour... java code:
ULogger.info("throwing out 666!");
System.exit(666);
bash wrapper:
eval ${COMMAND_TO_RUN}
ret_code=$?
printf "error code : [%d]" ${ret_code}
output:
[2012-11-30 15:20:12,971][INFO ] throwing out 666!
error code : [0]
what's the deal here? Thanks...
[EDIT]
The ${COMMAND_TO_RUN} is
((java -Xmx9000m -Dtoday_nix=20121128 -cp "/usr/lib/hadoop/conf" com.paypal.risk.ars.linking.task_fw.BaseRunnableProcess 3>&1 1>&2 2>&3) | tee /dev/tty) > batches_errors.log
Your problem is in your COMMAND_TO_RUN:
((java -Xmx9000m -Dtoday_nix=20121128 -cp "/usr/lib/hadoop/conf" com.paypal.risk.ars.linking.task_fw.BaseRunnableProcess 3>&1 1>&2 2>&3) | tee /dev/tty) > batches_errors.log
The last program called is tee, which will exit with status 0, overriding the exit
value of java.
You can use $PIPESTATUS, which is an array of return values in the pipe.
For example:
$ cat nonexistantFile | echo ; echo "e: $? p: ${PIPESTATUS[#]}"
Expected output:
e: 0 p: 1 0
cat will fail (exit code 1), echo will succeed (exit code 0). $? will be 0.
${PIPESTATUS[0]} will contain the exit code for cat (1) and ${PIPESTATUS[1]} the one for echo (0).
This is because $? is almost certainly giving you the return code of eval, which is succeeding here. Why are you including the eval call in there? Just call the COMMAND_TO_RUN

Categories

Resources