Calling java from PHP exec - java

I am doing the following in PHP:
exec('java -jar "/opt/flex3/lib/mxmlc.jar" +flexlib "/opt/flex3/frameworks" MyAS3App.as -default-size 360 280 -output MyAS3App.swf');
When I run this from the command line, it runs fine and finishes in a second or two.
When I run this command from PHP exec, the java process takes 100% CPU and never returns.
Any ideas?
I have also tried running the above command with '/usr/bin/java -Djava.awt.headless=true'.
I am running Mac OS X 10.5.5, MAMP 1.7, PHP 5.2.5

Turns out it was a bug specific to the PHP stack MAMP (http://www.mamp.info/).
Turns out any invocation of the JVM following fails under MAMP, e.g.:
exec('java -version');
The fix is to prefix the command with
export DYLD_LIBRARY_PATH="";
Also I realized there's no reason to use that method of invoking mxmlc.
So here's the final, working command:
exec('export DYLD_LIBRARY_PATH=""; mxmlc MyAS3App.as -default-size 360 280 -output MyAS3App.swf');

I manage to get this to work togheter with MAMP. The solution was to include the:
export DYLD_LIBRARY_PATH="";
in the exec call:
$argss = "export DYLD_LIBRARY_PATH=\"\"; /usr/bin/java -jar /Applications/yourjarfile.jar";
$resultXML = exec($argss, $output);

Is there a reason why your using the mxmlc jar file to compile your flex application? have you tried using the executable or an ant task, instead?
Maybe the compiling is taking too long so that your PHP script times out?

Exec is always tricky, on any language :-)
Try to:
use background execution (add &
symbol at the end)
use shell_exec instead
specify the full path to
java executable (may be the one
available to PHP is not the one you
need?)
run a simple HelloWorld java
app to see if the problem is in Java or
in mxmlc specifically
It's strange that java takes 100% CPU. I cannot explain it with any common mistake made when using exec()... try to send it a SIGQUIT to dump the threads, then read the dump -- may be you'll figure something out.

Related

Java JAR file does not execute in startup script in Ubuntu 14.04

The following process normally works for my startup scripts. However, when I introduce a command to execute a JAR file, it does not work. This script works while I am logged in. However, it does not work as a startup script.
In /etc/init.d I create a bash script (test.sh) with the following contents:
#!/bin/bash
pw=$(curl http://169.254.169.254/latest/meta-data/instance-id)
pwh=$(/usr/bin/java -jar PWH.jar $pw &)
echo $pwh > test.txt
Make script executable
In /etc/rc.local, I add the following line:
sh /etc/init.d/test.sh
Notes:
I make a reference to the script in /etc/rc.local, because this script needs to run last after all services have started.
Please do not ask me to change the process (i.e., create script in /etc/init.d/ and reference it from /etc/rc.local), because it works for my other startup scripts.
I have tried adding nohup in front of java command, and it still did not work.
Thanks
As written, there is insufficient information to say what is going wrong. There are too many possibilities to enumerate.
Try running those commands one at a time in an interactive shell. The java command is probably writing something to standard error, and that will give you some clues.

How to debug Java and Perl code in Eclipse in same debug session?

Setup:
I am working on a Java project which invokes some Perl scripts.
Problem:
If I run the Perl script from terminal, it works fine. But when I invoke the same Perl script with same arguments from Java code, it fails. It is an extremely strange and annoying bug.
I am able to debug Perl in Eclipse using EPIC plugin. And of course, I can debug Java code. It would be helpful to debug Java and Perl code in the same debug session in Eclipse, so that I can see whats different happening when the script is invoked via Java code.
Not sure if this is even possible, but if anyone has any idea, please share.
Thanks.
Perl has some remote debugging capabilities, so you can get what you need, I think. I don't use EPIC, so I don't know if you'll be able to do it all within Eclipse.
Set the environment variable named PERLDB_OPTS to have the value RemotePort=<host>:<port>. Then, start Perl with the -d flag. Instead of the debugger trying to interact with standard IO on the invoking terminal, it will attempt to connection to host:port.
Here's a Unix-y example. I've got a Perl script hello.pm and two terminal windows open.
First terminal
$ nc -l 12345
That's started NetCat as a dumb server listening on port 12345. If you don't have a server listening before Perl starts, it won't work.
Second terminal
$ export PERLDB_OPTS=RemotePort=localhost:12345 # set the env variable
$ perl -d hello.pm
Now the script is running. Back on the first terminal, I see
First terminal
main::(hello.pm:1): print "hello\n";
DB<1>
I'm in the Perl debugger and ready to go!
I know that at least the Komodo IDE has support for remote debugging, and there's a Perl Monks post on doing it with Emacs, so you can get something more than the command line even if it's not Eclipse. Good bug hunting!
If I run the Perl script from terminal, it works fine. But when I invoke the same Perl script with same arguments from Java code, it fails.
I suggest that you check that you are running the same version of Perl in the two "contexts"; i.e. when the Perl app is run from the command line and from Java.
If that's not the problem, check the environment variables.
The other approach to solving this problem would be to focus on why the program is going wrong, not on how / why the contexts are different. Look at the evidence that you have, and look at ways to gather more evidence ...
The potential problem with trying to do this using a Perl a debugger (in an IDE or stand-alone) is that you are actually running Perl in third "context" which might be different from either or both of the existing ones.
Using a debugger may work ... or it may leave you even more confused.

Java: How to run a Java process in a specific directory?

When I run a jar file, say in /home/jars like such java -jar /home/jars/jarfile.jar, it seems to run in whatever directory I'm in.
How do I make it so java -jar /home/jars/jarfile.jar runs with /home/jars as the current working directory??
The simple answer:
( cd /home/jars; java -jar /home/jars/jarfile.jar )
See also this response.
The analogy for most languages supporting an exec call, is the variant of exec that lets you specify a working directory.
See this for simple PHP solution.

What are the differences between Java's java.lang.Runtime.exec() and PHP's exec()?

The following doesn't work in Java (an exception is thrown):
Runtime.getRuntime().exec("cd mydir; myprog");
The same works fine in PHP:
exec("cd mydir; myprog");
What exactly is different in Java's implementation and why (it seems more limited at first glance)?
the java exec command does not use the system command interpreter. something like "cd mydir; myprog" depends on the system command line interpreter (e.g. on windows cmd, on linux sh) to split that into 2 separate commands and execute each of them. java does not invoke the system command interpreter, so that does not work. you either need to call each command separately, or invoke the desired interpreter yourself as part of the command line.
I've seen people have problems like this, and I'm sure there are several ways, however the one I've seen most people reply is this. add cmd before it.
Runtime.getRuntime().exec("cmd cd mydir; myprog");
Assuming you're running an applet, not Java in a CLI environment on the server? If so, then your Java runtime is running on the client computer, not the server.
Java also has a better way to handle multiple commands than your semicolon. Instead of using the signature:
Runtime.exec(String)
try using this for each of your commands:
Runtime.exec(String[])
and make each argument of your command an element in the String array.

Running a java application through shell script in a JSP/Servlet

I am running a shell script through a web application. This shell script looks something like
`#! /bin/bash
user=""
pass=""
db_url=""
db_instance=""
sqlplus -s $user/$pass#$db_url/$db_instance # ./SqlScripts/foo.sql
sqlplus -s $user/$pass#$db_url/$db_instance # ./SqlScripts/bar.sql
CLASS_PATH="./lib/*"
java -classpath $CLASS_PATH package.Main ./Data/inputfile`
I am using ProcessBuilder to run the script and everything but the last line works fine. Am I creating a problem by calling shell through the jvm then calling the jvm again to run the application?
The problem was the environment that the script execution process was running in. I changed some of the environment variables of the process and everything is working fine now. The script was initially a standalone shell script, but I wrote one script for each of the databases used. In order to control the workflow I wrote a web application for this which calls seperate threads for each script and can manage the threads. Thanks for the responses!
Often, app servers run their servlets in a 'clean room' environment - e.g. they strip away all the variables that would normally be set from the outside for security reasons. Try using a fully qualified path to the java binary, and also try setting a full/absolute path for your CLASS_PATH variable.
The parent JVM and the child JVM should be separate processes, no particular reason why they should interfere.
What error do you get?
is java on your PATH?
OK, adding more questions in response to your comments ...
Which thread is waiting? Presumably the parent?
The child java process, do you have any evidence as to whether is succesfully initalises. My guess woukld be that the child is in some way blocked. If you kill the child does the parent then come back to life?
Suppose it was a simple "hello world" application, would that work?
Most likely the line:
CLASS_PATH="./lib/*"
And
$CLASS_PATH
It won't be expanded by the process builder because that's usually shells' job, which in this situation is not being invoked.
Try creating the complete list of ./lib/* and append it directly into the last line of your script.
java -classpath ./lib/a.jar:./lib/b.jar
Side note:
Invoking all this from java looks just bad to me. I would rather have it in a standalone script and invoke it by other means, but that's me.

Categories