linux - bash command fails in tomcat/java Runtime.getRuntime.exec(), but works from command line -
i have tomcat webapp runs process in shell because several of utilities not available in java. this code works on other machines, there mysterious problem on public server.
string[] textanalysispipeline = { "/bin/sh", "-c", "/bin/cat " + inputfileloc + " | tee /tmp/debug1 | " + loadjar + " " + jaroptlookuploc + " " + opthfstloc + " 2>/dev/null | " + "tail -n+5" + // rid of header hfst-ol.jar produces " | tee /tmp/debug2 | cut -f 1-2" + // rid of "0.0" weights " | tee /tmp/debug3 | " + cgconvloc + " | tee /tmp/debug4 | " + vislcg3loc + " -g " + vislcg3disgrammarloc + // disambiguate constraint grammar " | tee /tmp/debug5 > " + outputfileloc}; log.debug("text analysis pipeline: "+textanalysispipeline[2]); process process = runtime.getruntime().exec(textanalysispipeline); process.waitfor();
i print string log, , looks this: (path/to/
not actual paths)
/bin/cat /path/to/inputfile | tee /tmp/debug1 | java -jar /path/to/hfst-ol.jar /path/to/analyser.ohfst 2>/dev/null | tail -n+5 | tee /tmp/debug2 | cut -f 1-2 | tee /tmp/debug3 | /usr/local/bin/cg-conv | tee /tmp/debug4 | /path/to/vislcg3 -g /path/to/grammar.rlx | tee /tmp/debug5 > /path/to/outputfile
if copy pipeline log , run bash command line, desired output way end of pipeline. however, when tomcat server runs command, produces empty file. debug files debug1
, debug2
expected, debug3
, thereafter empty, suggests pipeline fails @ cut -f 1-2
(see update 1 below).
os - fedora 22
java - openjdk 1.8.0_77
tomcat - 7.0.39
sh --> bash - 4.3.42(1)-release
================================================================
update 1:
this not seem problem cut
. wrote short python script, cut.py
achieve same functionality cut -f 1-2
(remove '\t0.0'
end of each line)
import re, sys myre = re.compile( r'\s+0\.0$' ) line in sys.stdin : sys.stdout.write( myre.sub( '', line ) )
using cut.py
in place of cut
, same problem. server debug3
, beyond empty, if copy-paste log interactive shell, works fine.
================================================================
update 2:
i wrote simple bash script run pipeline tomcat/java runs bash script 1 argument input/output filename. if run script interactive shell, works, results no different in tomcat, using cut
or cut.py
in shell script.
by default installation on systems, tomcat not have same environment user. not run, instance, .bashrc .profile or whatever have in login script, variables set in user shell environment different.
you can check comparing env
command both users: yours , having called java program, like:
string[] textanalysispipeline = {"/bin/sh","-c","/usr/bin/env > /tmp/env.txt"}; //or wherever 'env' command in system process process = runtime.getruntime().exec(textanalysispipeline); ...
and compare content of /tmp/env.txt
env
execution user... different.
look following variables:
- path
- classpath
- java_home
i have same problem in past. suggest following approach:
use absolute path everything, including calls "java", "tee", "tail" , libs (jar files)... have in command;
change environment configuration under tomcat runs reach applications call in command (usually calling script configures necessary
path
variable (do not forgetjava_home
,classpath
jar files!). check startup.sh , catalina.sh suitable place include stuff;change command redirect error output not
/dev/null
in message, log file somewhere in system application can write (usually/tmp/exec.log
fine) can sure of shell execution problem. bet like:sh: ****: command not found
orerror: unable access jarfile
or message of application not being able locate object, sure of application call in script not inpath
environment variable or libs don't have in it... both
for additional info on this, check https://www.mulesoft.com/tcat/tomcat-classpath
hope helps...
Comments
Post a Comment