I have a matlab script that takes an input mat file and produces an output file.
Currently I have a shell script that is able to execute this script.
I am executing this script from Java using ProcessBuilder class and all is working well.
I need to perform the matlab script execution very often from java and each time script executes the mcr process is created, script executes and mcr terminates.
i like to have the MCR process open and have a matlab session open towards java , so that same process is kept alive so i can execute scripts multiple times in the same session.
I find matlabcontrol seems to be suitablefor this.
How to configure the MatlabProxyFactory with the MCR location and LD_LIBRARY_PATH
which i am setting in my shell script and execute my script in a same session?
I also came across a tool MATLAB JA Builder but i cannot use this at the moment as its not Free.
Thanks!
If you are using matlabcontrol I don't think you need the shell script, just tell it the name of the m-file you want to be run. If you want to keep the shell script in conjunction with a ProcessBuilder, you have to start the process once and keep a reference to its input stream. When you want a command executed, you write it that stream. Also, you have to keep a thread alive to empty the output and error streams of Matlab, otherwise they will get full and Matlab will hang. If you want to go with this, I recommend looking at the source of this project (which I am a contributor to). The class you are interested in is RCaller. It does more or less the same, except it invokes R and not matlab.
Related
How can i invoke batch file without fork in java?
I use NSSM command-line interface to install my product as windows service. I always use Runtime.exec() to operate with command-line. I bypass bytes from new process's streams and periodically check for it finish job. I wonder, if there is easy way to use command line? I don't need forked process, is there a way not to use it? I want just call some exec("command") function, which acts as simple procedure.
You cannot do the equivalent of Unix / Linux exec() syscall or the Posix shell exec command ... without forking ... in Java. It is not supported by the standard Java class libraries.
It may be possible to write a native code method to call the OS-provided native libraries to do an exec or equivalent. However, this could behave in unexpected ways (e.g. no shutdown hooks) and would definitely be non-portable. And in the case of Windows, I don't think it is possible to do the equivalent of UNIX exec without fork: source Wikipedia.
However, you can easily run a batch file from Java:
How do I run a batch file from my Java Application?
But I don't understand the point of doing an exec to run a batch file instead of the normal fork / exec ... which is what Runtime.exec() does under the covers. Perhaps if you explained, we could understand why you need to do it, and offer a suggestion.
I need to execute a shell script in a java program. I figured out that i can use processbuilder and runtime.exec.. but my webserver times out every 180 sec but my script execution takes more than that..i do not want to use process for this approach.. is there any other way where i can use thread for this execution.
thanks.
I'm assuming that the response from the script is intended for humans to read.
Good interface design, and human nature, suggests that if your script is taking over 180 seconds to run, then it should be run separately from the web server. On linux, I would suggest putting it into 'cron', and letting it run on a regular basis. You would only serve the results of the script via the web server, with a response time in seconds instead of minutes.
If your script depends on parameters from the http request, or other information that is only available from within the web server's environment, you have the following choices.
If you can figure out the likely combinations of parameters, run the
script automatically for each combination of parameters,
again only serving the results through the web.
If the majority of the time is spent in a single command, and the
results of that command don't change much between runs, move that
command into a separate script that runs automatically, and use the
results of that separate script to build the web response.
Break the response up into segments, only showing a portion of the
data for each request, allowing the user to page through the
response. The script would be rewritten to only request the
necessary data for the current page, reducing the amount of time
needed to obtain that data.
Rewrite the script in a compilable language, which might gain you enough time to make running it for every request reasonable. However, if the problem is a database query, this won't do you any good. You'd have to go with option (3), whether you rewrote it in a compilable language or not.
Without additional information, like an example of the script, or a description of where you're getting the results from, that's the best I can do.
A process can run several threads, but they still are parts of the process.
So, all threads inside a java program are the threads of the java process, and a thread cannot run another program's threads.
A shell script is ran by a program : the shell program ! (/bin/bash or /bin/sh)
Anyway a shell script will mostly ran other programs inside several other processes.
No, you cannot run a shell inside a thread of java.
In general, if you have code that is separate from your Java program, such as code that is in a separate script, then there is no justification for why your code would execute an outside script when that code could be instead integrated into the program. It is insecure at best. Your basically allowing arbitrary code to be executed by your program since the outside script is editable. What you are doing sounds to me almost like it should be confined either a unit test or a build task.
As a unit test task and you could use a threaded JUnit runner to run your outside script during the test phase of your project.
Also, separately from your program, you could also execute it using a Gradle task and by using the parallellforks option that Gradle has.
I have a very strange situation where a Java process seems to hang when called via Apache/PHP, but OK when invoked from the command line. I spent hours debugging this, no avail. Any and all thoughts welcome!
Situation: I have a .class file (without the original Java code) that reads an input file, processes the read information, and writes a report on stdout. The Java code doesn't read stdin, and only writes stdout. I wrapped this in a tiny Perl script that basically just execs "java -cp /path/to/classfile MyJavaProgram /path/to/inputfile/to/process". That way I can invoke it from the command line for testing, this works like a charm. Next, I try to invoke this from PHP using popen(), and there Java just hangs. I see the Perl process in the ps list, and Java; but the Java process waits forever. Once I kill it, the webserver page continues loading (but of course without the expected output that the Java process would generate).
What I tried so far:
Wrapping the Java process in a shell script, same behaviour. Java just hangs.
Running it from PHP with popen() without a wrapper, same behaviour.
Starting it from PHP with system() or passthru(), same behaviour.
In the Perl wrapper, reopening STDIN for /dev/null (so that reading stdin immediately returns EOF), same behaviour.
In the Perl wrapper, reopening STDERR for /dev/null, same behaviour.
In the Perl wrapper, reopening STDOUT for /dev/null. Here I would expect no output (as it gets discarded) but still the Java process just hangs.
In the Perl wrapper, reopening all 3 streams for /dev/null. Java still hangs.
Replacing the Java invocation in the Perl wrapper with a simple "ls -l /bin". This works as expected; the web page gets populated with the "ls" listing. So the problem isn't in PHP or Perl.
Starting the Java process with a "/bin/sh -c 'java .....'". Same behaviour, Java hangs.
In the Perl wrapper, I dump the environment variables too, to check them. Environment seems OK.
When the Java process is running, I look up the Perl wrapper invocation in the ps list, and copy/paste it to the command line. Works like a charm.
Similarly, when the Java process is hanging, I look up the invocation in the ps list, and copy/paste it to the command line. Works like a charm.
I also verified that the the input file is readable when invoked from the web server. All above tests with the command line were run using the same user ID as the Apache user.
Unfortunately I can't replace the Java code with something that's under my control. I only have the .class file to work with. What I haven't tried yet is to run this under Linux, so this still might be an OSX specific issue (which would surprise me).
What the hell is going on here? Any and all "wild" ideas appreciated.. thanks!
Check ALL environment from apache AND from cmd line, including the paths, UIDs etc.
Also check what the java process does when hanging (use truss/tusc/strace -f java xxxxxxxxxxx 2>/tmp/trace.$$ ) when wrapping it from both places (apache and cmdline), then compare the results.
Also, when wrapping from perl, set autoflush to 1 for stdin, stdout, stderr before exec-ing java.
I have several java processes running on a windows machine. I have a Java process which is supposed to monitor the other processes and periodically kill or restart new ones.
If I have a java process running com.foo.Main1 and one running com.foo.Main2 - how can my monitoring process find and kill just the Main2 process?
Update: I have some code that can execute a command line tasklist.exe and parse it, but no matter what I do, I only see the java.exe process, not which class is executing
Update 2: I do not have the ability to install non-java programs.
It's probably going to be a lot simpler using OS-specific tools and using Runtime.exec() to run them, but I'll try and give a platform independent answer:
It might be possible to do this platform independently using the Attach API. This comes with the JDK, so to use it just include tools.jar from your JDK on your program's classpath.
To get a list of virtual machines on the system, use VirtualMachine.list(). You can get/parse arguments from the virtual machine descriptor objects that are returned from this.
The attach API also allows you to load agents into already-running Java processes. Since you want to kill a Java process, you can write a Java agent that simply runs System.exit() (or if you really want it dead use Runtime.halt() instead) when the agent loads.
Once you identify the one you want to kill, attach to it and load the killer agent (the agent has to be built as a JAR file, accessible to the Java process it needs to be loaded into). Shortly after the agent is attached that process should die.
These links might help also:
An Oracle blog on the attach API
Package documentation for java.lang.instrument (has detailed instructions on how to build an agent JAR)
This is specific to Windows.
I was facing the same issue where I have to kill the specific java program using taskkill. When I run the java program, tasklist was showing the same program with Image name set as java.exe. But killing it using taskkill /F java.exe will stop all other java applications other than intended one which is not required.
So I run the same java program using:
start "MyProgramName" java java-program..
Here start command will open a new window and run the java program with window's title set to MyProgramName.
Now to kil this java-program use the following taskkill command:
taskkill /fi "MyProgramName"
Your Java program will be killed only. Rest will be unaffected.
I'm looking to create a Java Application that is able to run windows commands in a "batch" manner; what I mean by this is that it's persistent in between commands and isn't as if you're only executing one at a time.
An example of this might be:
#echo off
pushd C:\foldertobepushedto\
call batchfiletobecalled.bat
popd
pushd anotherdirectorytobepushedinto
call anotherbatchfiletobecalled.bat
popd
I would like to be able to use the Process process = Runtime.getRuntime().exec(CMD); manner to be able to run each of these lines but kept persistent so that it's not as if each line is run completely separate from the rest of them.
I hope I am making a bit of sense; I intend to essentially remove the use of batch files all together and store each line as an element in a vector/array and execute them "batch" style that way.
Excuse me. I know a way to solve this problem in JScript; I ignore if there is an equivalent method for Java.
You may achieve the desired effect you want if you:
Execute CMD.EXE file alone with NO parameters, but via WshShell.Exec method:
var WshShell = new ActiveXObject("WScript.Shell");
var oExec = WshShell.Exec("cmd");
WshShell.Exec method provide access to the process standard I/O channels.
After that, send to the process' STDIN channel the commands you want to execute:
oExec.Stdin.WriteLine("#echo off");
oExec.Stdin.WriteLine("pushd C:\foldertobepushedto\");
oExec.Stdin.WriteLine("call batchfiletobecalled.bat");
oExec.Stdin.WriteLine("popd");
oExec.Stdin.WriteLine("exit");
This way, all commands will be executed in a way entirely equivalent as if they would be included in a Batch file. The only difference is that certain commands will not be correctly executed, like GOTO.