Run a .java file using ProcessBuilder - java

I'm a novice programmer working in Eclipse on Windows XP, and I need to get multiple processes running (this is going to be a simulation of a multi-computer system). My initial hackup used multiple threads to multiple classes, but now I'm trying to replace the threads with processes.
From my reading, I've gleaned that ProcessBuilder is the way to go. I have tried many many versions of the input you see below, but cannot for the life of me figure out how to properly use it. I am trying to run the .java files I previously created as classes (which I have modified). I eventually just made a dummy test.java to make sure my process is working properly - its only function is to print that it ran.
My code for the two files are below. Am I using ProcessBuilder correctly? Is this the correct way to read the output of my subprocess? Any help would be much appreciated.
David
Edit: The solution is to declare ProcessBuilder("java.exe","-cp","bin","Broker.test");
primary process
package Control;
import java.io.*;
import java.lang.*;
public class runSPARmatch {
/**
* #param args
*/
public static void main(String args[]) {
try {
ProcessBuilder broker = new ProcessBuilder("javac.exe","test.java","src\\Broker\\");
Process runBroker = broker.start();
Reader reader = new InputStreamReader(runBroker.getInputStream());
int ch;
while((ch = reader.read())!= -1)
System.out.println((char)ch);
reader.close();
runBroker.waitFor();
System.out.println("Program complete");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
subprocess
package Broker;
public class test {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("This works");
}
}

You are calling the java compiler on the .java file, this will not run the class. What you probably want to do is running java.exe on your .class file. (ie something like "java.exe -cp ./bin Broker.test", assuming your class files are in ./bin)

Related

I am trying to execute an exe in Java which is developed in Dotnet

The code in java was made to run a .exe file created in .NET platform and the code was shown to be running successfully. The process even showed to be alive when called with isAlive() function but doesn't run. The .exe did not run, i.e. was not shown anywhere in task manager. Also I checked it with waitFor() methood.
Further i need to run this on a Java Servlet please suggest me if what i can do to make this run, Thanks in advance
The code is as below:-
public static void main(String[] args) {
try {
ProcessBuilder pb = new ProcessBuilder("D:\\J2EEeclipse-workspace\\TARecruiter\\WebContent\\WEB-INF\\Debug\\Sharpenter.RP.UI.Console.exe");
Process p=pb.start();
System.err.println( p.waitFor());
} catch (IOException | InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
The below-provided code-snippet would work and initiate the process. Which can be viewable in the task manager. To make it work currently create a .java code with the provided snippet in the folder where the .exe file exists and run the code. Now you can make this code as a thread and call anywhere in your program as a thread to make it work. This certainly is not the final solution, but until the time I get to the actual reason keep working.
try {
Process
p=Runtime.getRuntime().exec("Sharpenter.ResumeParser.UI.Console.exe");
try{ p.waitFor();
}catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Done.");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();

Matlab Compiler SDK plot waitforFigures function multiple threads

I have created a simple plot with matlab and created a java jar with matlab compiler sdk.
I can run the java function created by matlab and see my plot.
I wanted to create multiple plots and started the function in separate threads.
It works. But if i start my java function for creating multiple plots, the waitforFigure() method of the first thread is waiting for the other plots to be closed too. So my first thread does not continue and blocks till the other plots who are created after it also are closed.
I thought instantiating a Object of the Java class, produced by the Matlab compiler SDK creates a new Matlab compiler runtime?!.
Why is the waitforFigure method waiting for the other plots too, if it is run on seperate thread?
Here is my function runFunction of the RunAlgorithm class i created.
The runFunction methods instantiates the Matlab Compiler SDK created Class, Class1. Its the default name of the class. The thePlot function is the matlab code running in the Matlab runtime and plots my data.
void runFunction( MWNumericArray x1, MWNumericArray y1, MWNumericArray z1) throws MWException {
Class1 thePlot = new Class1;
/* Number of points to plot */
try {
/* Plot data */
thePlot.runAlgorithm( x1, y1, z1);
thePlot.waitForFigures();
}
catch (Exception e) {
System.out.println("Exception: " + e.toString());
}
finally {
/* Free native resources */
MWArray.disposeArray(x1);
MWArray.disposeArray(y1);
MWArray.disposeArray(z1);
if (thePlot != null)
thePlot.dispose();
}
}
Here my simple thread how it executes the Function containing my Matlab class.
I instantiate the RunAlgorithm class, read data from file, and pass it converted to MWNumericArray to the runFunction method.
In my runFunction method there is the waitforFigures method blocking.
Thread t1=new Thread() {
public void run() {
RunAlgorithm a = new RunAlgorithm();
RunAlgorithm.Measurements n = null;
try {
n= a.readFile(selectecValue);
System.out.println("File REad");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
a.runFunction(n.mX, n.mY, n.mZ);
} catch (MWException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
t1.start();
Basically i read a csv File, parse my Data in to MWnumericArray, and pass it to the RunAlgorithm class. That Class internally creates the Class1 Object with the runFunction and plots my Matlab- Plot with Matlab runtime.
EDIT:
If i run my application twice. The waitforFigure method is just waiting for the threads generated by one application.
That would mean, the matlab runtime is run once with the application, independent from the threads i created?
So the Class1 instantiation is not starting a new matlab runtime everytime?
EDIT:
If i compile my matlab code as Singleton,then my plot is refreshed. That would mean, the instatiation of my Class1 Object is starting a new matlab runtime ?
I had a look into your problem and tried to create a Matlab jar on my machine. However, for some reason, creating a jar file failed, so instead I created a dll for .net application. The underlying principle should be similar anyway.
Here is a snap of the constructors found in the generated C# code:
private static MWMCR mcr= null;
static Plotter()
{
if (MWMCR.MCRAppInitialized)
{
try
{
/* a lot of codes here but deleted to make what is important stands out */
mcr= new MWMCR("",
ctfFilePath, embeddedCtfStream, true);
}
catch(Exception ex) { //some code here }
}
}
public Plotter()
{
if(ex_ != null)
{
throw ex_;
}
}
And the drawplot() method which tells the Matlab runtime to run the packaged M-script.
public void drawplot()
{
mcr.EvaluateFunction(0, "drawplot", new MWArray[]{});
}
As you can see, the MWMCR class is the actual Matlab instance that runs the M-script and it is a static object. Therefore, no matter how many Plotter or Class1 is instantiated, there is only one Matlab instance. Multiple mcr.EvaluateFunction requests are queued and executed one after one. Therefore, theoretically running multiple Matlab scripts simultaneously is not possible without having two MWMCR objects generated, which means you will need multiple instances of your java assembly (experimentally confirmed).
In your case, all figures are plotted by the same instance of MWMCR, and WaitForFiguresToDie or waitForFigures() checks for any unclosed figures plotted by MWMCR.
public void WaitForFiguresToDie()
{
mcr.WaitForFiguresToDie();
}
A solution I can propose to you is to include an empty Matlab code (EmptyCode()) in your jar package. Then implement something similar to the following in your java code:
void runFunction()
{
Class1 thePlot = new Class1;
Thread t1=new Thread() {
public void run() {
Class1 thePlot = new Class1;
thePlot.waitForFigures();
}
}
Thread t2=new Thread() {
public void run() {
Class1 thePlot = new Class1;
thePlot.waitForFigures();
}
}
thePlot.waitForFigures();
t1.start();
t2.start();
//your java code
thePlot.EmptyCode();
thePlot.waitForFigures();
}

Execute java in shell and wait until i get the return code

I am now executing java a java program like this:
package com.test;
public class Test {
public static void main(String[] args){
execute();
}
public static String execute(){
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "a";
}
}
I want to execute the Test.execute() method in linux shell script, wait until the method return and get return code . but the return of main() method is void , so what Can I do the get a return code or return msg from it ?
Any suggestions?
I find a solution:
package com.test;
public class Test {
public static void main(String[] args){
execute();
}
public static String execute(){
try {
System.out.println("sleeping");;
Thread.sleep(5000);
Runtime.getRuntime().exit(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "a";
}
}
And then my shell:
#!/bin/bash
java -cp test.jar com.test.Test
echo "The return code of the java application is $?"
I can get the value n which is in Runtime.getRuntime().exit(n);
First change the signature of main method in your code example:
public static void main() to public static void main(String[] args)
Then instead of just calling the execute method from main, try to print the result using System.out.println :
System.out.println(execute());
and then in linux shell you can use following to get the return values:
> set out = `java com.test.Test`
> echo $out
The shell script would have to call java com.test.Test. And this will call the main method which inturn is currently calling execute.
From a shell script you would have to start a JVM and a JVM always starts with a Main method.
As for the return code, you can access it using the $? shell variable.
So basically your shell script would be something like this:
#!/bin/bash
java -cp . com.test.Test
echo "The return code of the java application is $?"
Also you need to specify the classpath where all you relevant classes reside. In the above example I am putting in the current dir as the classpath.
The JVM will terminate with a exit code of 0 on completion of all non-daemon threads. If you want to return a specific exit code in case of an error you can use System.exit(<codehere>). Please note that calling System.exit() will cause the JVM to shutdown even if there are other non-daemon threads that are running.
Edit:
Added "-cp ." to the command based on the comments.
Added some exit code details

Get updated copy of environment variable in java

I want to get latest/updated copy on environment variable using java.
Java is not returning latest copy if someone changed particular environment variable after running a programme.
please use below sample code to test the scenario.
import javax.swing.JOptionPane;
public class Test extends Thread {
public static void main(String[] args) {
Test test = new Test();
test.start();
}
#Override
public void run() {
super.run();
while (true) {
JOptionPane.showMessageDialog(null, System.getenv("A"));
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Update:
Tried ProcessBuilder also
ProcessBuilder processBuilder = new ProcessBuilder("echo %A%");
System.out.println(processBuilder.environment().get("A"));
The environment variables are set when the JVM starts and will not change.
That is generally true for all Windows programs. E.g. start a Command Prompt, change an environment variable through the Windows Control Panel, and the Command Prompt will not see the changed value.
Only Command Prompts opened after the change will see the change.

Why Visual VM shows instances as zero for this String class?

This is my sample program which creates a String Object
public class TestingHeap {
public static void main(String args[])
{
String str = new String("Hi This is sample String");
try {
//Thread.sleep(1111111);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
When i viewed the Heap Dump under VisualVM Tool the instances for that class is shown as zero
This is the screenshot wrt to above statement
If my assumption is wrong could you please let me know how to see the Objects present under Heap ??
Because your main() method is static and your code doesn't create an instance of TestingHeap. You could do so,
TestingHeap th = new TestingHeap(); // <-- add to main.

Categories

Resources