How to run a .jar file from inside another java program? - java

i have a .jar file, which I can run on the command line:
java -jar myFile.jar argument1
I want to save the output of this .jar as a String variable inside another java program.
How can I do it?
I tried including myFile.jar as a reference in my program, and doing myFile.main(new String{"argument1"}) in my program. But this just prints the results to console, I can't use the results in my program.
Hope this is not too confusing.

I
Running Jar file require you to have the jar file included in your class path. This can be done at run time using URLClassLoader. Simply construct a URLClassLoader with the jar as one of the URL. Then call its forClass(...) if you know the class name (full name of course). Or inspect the manifest file using its 'findResources(String name)'.
Once you get the class, you can use reflection to get its static method main.
Seeing your question again, you know the class name, so if you are sure the jar file in already in the class path, then you can just call it as you tried.
II
To capture the output, you can call System.setOut(PrintStream out) and System.setErrPrintStream out) to change the print stream. You can pass the printstream that you create. Like this:
ByteArrayOutputStream BAOS = new ByteArrayOutputStream();
PrintStream MyOut = new PrintStream(BAOS);
System.setOut(MyOut);
// Do something to have something printed out.
...
String TheCaptured = new String(BAOS.toByteArray());
Hope this helps.

If you can't include the other jar,
you can use something like that
Runtime re = Runtime.getRuntime();
BufferedReader output;
try{
cmd = re.exec("java -jar MyFile.jar" + argument);
output = new BufferedReader(new InputStreamReader(cmd.getInputStream()));
} catch (IOException ioe){
ioe.printStackTrace();
}
String resultOutput = output.readLine();
I know my code isn't perfect like the catching exception, etc but I think this could give you a good idea.

Being a Jar file, you can add it to your class path and call the functionality of the program your self. You might need to know more about the logic behind the Jar to use it without having it output the information..
I believe what you are looking for is how to shell execute the Jar archive. An example can be found here.

Take a look at ProcessBuilder:
http://java.sun.com/javase/6/docs/api/java/lang/ProcessBuilder.html
It effectively creates an operating system process which you can then capture the output from using:
process.getInputStream().
The line:
processbuilder.redirectErrorStream(true)
will merge the output stream and the error stream in the following example:
e.g.
public class ProcessBuilderExample {
public ProcessBuilderExample() {
// TODO Auto-generated constructor stub
}
public static void main(String[] args) throws IOException, InterruptedException {
ProcessBuilder pb = new ProcessBuilder("java", "-jar", "gscale.jar");
pb.redirectErrorStream(true);
pb.directory(new File("F:\\Documents and Settings\\Administrator\\Desktop"));
System.out.println("Directory: " + pb.directory().getAbsolutePath());
Process p = pb.start();
InputStream is = p.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
for (String line = br.readLine(); line != null; line = br.readLine()) {
System.out.println( line ); // Or just ignore it
}
p.waitFor();
}
}

Related

Use ProcessBuilder to capture output of separate package

I have a project that uses ProcessBuilder to capture the output of the command "java -jar someJar.jar -argument", but have now moved the jar's source files to a separate package; somepackage. The package has a main function, so I would like to create a ProcessBuilder that captures the output of that process, as if it were a different Thread.
Is this possible, or will I have to completely re-write the code to allow it to use the source files instead of the binary?
If I'm assuming right, the package has main function and we are trying to get output of the main method that executes with java -jar processbuilder command.
ProcessBuilder pb = new ProcessBuilder(your java -jar command);
Process process = pb .start();
process.waitFor();
BufferedInputStream in = new BufferedInputStream(process.getInputStream());
byte[] contents = new byte[1024];
int jwtOytputBytesRead = 0;
String Output = "";
while ((jwtOytputBytesRead = in.read(contents)) != -1) {
Output += new String(contents, 0, jwtOytputBytesRead);
}
System.out.println(Output);
Try this link as well to specify the main the class
Run class in Jar file

How to execute a console command in a Java application?

I am developing a Java application which will execute a console command. What the command actually does is, it will make changes to a file, then will save a copy of it with a different name to a different folder (both of the file and the output folder is specified by the user). And it requires some binary program to do this, which is a local resource of my application.
So my code is something like:
...
public void actionPerformed(ActionEvent e) {
File selectedFile = jFileChooser1.getSelectedFile();
File pathAssigned = jFileChooser2.getSelectedFile();
String file = selectedFile.getAbsolutePath();
String output = pathAssigned.getAbsolutePath();
String name = selectedFile.getName();
// What's next???
}
And the usage/syntax of the command is something like:
"command -options /package/binary.bin "+file+" "+output+"\\"+name+"-changed"
So my question would now be; What will be my next code? Should I use a Runtime? If so, then how?
And about including a local resource path to a command, does my syntax is correct?
I am still a newbie here as well as in Java programming so please be kind to your answers/comments. Thanks!
PS. The command is a platform independent by the way.
I hope the code below can help you. First you have a shell script that takes parameters.
#!/bin/bash
echo "hola"
echo "First arg: $1"
echo "Second arg: $2"
You save it in e.g. /home/dac/proj/javatest2016/src/main/java/myshellScript.sh and then you can pass the parameters from your Java code.
import java.io.*;
public class Main {
public static void main(String[] args) throws Exception {
try {
ProcessBuilder pb = new ProcessBuilder("/home/dac/proj/javatest2016/src/main/java/myshellScript.sh", "myArg1", "myArg2");
pb.directory(new File("/home/dac/proj/javatest2016/src/main/java"));
Process p = pb.start();
StringBuffer output = new StringBuffer();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = reader.readLine())!= null) {
output.append(line + "\n");
}
System.out.println("### " + output);
} catch (Throwable t) {
t.printStackTrace();
}
}
}
Test
### hola
First arg: myArg1
Second arg: myArg2

cannot run/get output from runtime.getruntime.exec() (android java)

I have a php executable native binaries that came from some php server apps in play market, and I tried them on my tablet using a shell app.
I'm creating a new app and trying to run it and receive the output but it doesn't work.
I've a function that does copy the assets to the device. I also have some code to test that they are there properly
File file4 = new File(getFilesDir().getAbsolutePath()+"/php");
file4.setExecutable(true);
s+=file4.getName();
s+=file4.exists();
s+=file4.canExecute();
s+=file4.length();
it does say correct filename exists, is executable and correct file length.
Now, I try to run it it doesnt give me the php output.
I've tried php -v for version output, doesn't work.
I've tried php phpfile.php >> file.html and read the file, doesn't work.
I've tried with -f and also without -f but it doesn't work.
Lastly, I tried giving the parameters and working dir separately to .exec and still it gives no proper output
When I tried runtime.getruntime.exec with other commands like /bin/cmd/ls ... it gives a correct output.
The php binaries do work, I've tried 2 of them on my device, none work in my app.
I would appreciate help.
s+=runphp();
public String runphp(){
try {
String prog= "./php";
String[] env= { "-f", getFilesDir().getAbsolutePath()+"/phprun.php"}; // ">>","phpoutput.txt"
File dir= new File(getFilesDir().getAbsolutePath());
Process p = Runtime.getRuntime().exec(prog,env,dir);
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line=null;
String output="";
while ((line = in.readLine()) != null) {
output += line;
}
in.close();
p.waitFor();
return output;
} catch (IOException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
The function does work for other commands.
The method Runtime.exec(String prog, String[] envp, File directory) requires you to give environment in the form name=value in the String[] envp.
But you are using it to pass arguments to your php program.
Use the following method instead,
Process exec (String[] progArray, String[] envp, File directory);
and pass all your command line arguments too in the first array itself.
Your command should look like:
String[] progArray= {"./php", "-f", getFilesDir().getAbsolutePath()+"/phprun.php"}; // ">>","phpoutput.txt"
File dir= new File(getFilesDir().getAbsolutePath());
Process p = Runtime.getRuntime().exec(progArray,null,dir);

Reading InputStream from Java Process

Im trying to open a terminal console, and be able to read / write commands to it.
I read some questions like:
Java Process with Input/Output Stream
With that was able build a little app that opens the terminal and pass commands to the console and print the result back, it works well with any system comand like browsing folders, deleting files and stuff like that.
The problem I have is that I need to load another java program from that console and read its output but that program uses java.util.logging.Logger to send most of its output and for some reason my launching app can't read what Logger prints.
Basically Im trying to build like a wrapper for another java app, because I want to interact with it but cant modify it.
Thanks for your help.
EDIT
Here is the code, but its basically taken from another questions, also as I said it works for things in the "normal" stdout, but not for the output Logger prints to the console.
package launcher;
import java.io.*;
import java.util.Scanner;
public class Launcher {
public static void main(String[] args) throws IOException {
String line;
Scanner scan = new Scanner(System.in);
Process process = Runtime.getRuntime().exec("/bin/bash");
OutputStream stdin = process.getOutputStream();
InputStream stderr = process.getErrorStream();
InputStream stdout = process.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(stdout));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stdin));
while (scan.hasNext()) {
String input = scan.nextLine();
if (input.trim().equals("exit")) {
writer.write("exit\n");
} else {
writer.write("((" + input + ") && echo --EOF--) || echo --EOF--\n");
}
writer.flush();
line = reader.readLine();
while (line != null && !line.trim().equals("--EOF--")) {
System.out.println("Stdout: " + line);
line = reader.readLine();
}
if (line == null) {
break;
}
}
}
}
Without seeing any code/config, I would guess that either the logger is configured to write to stderr (System.err) and you're only reading stdout (System.out), or else the logger is configured to write to a file.
Per dty's answer, I think by default java.util.logging uses stderr, so you should redirect stderr to stdout like this:
ProcessBuilder builder = new ProcessBuilder("ls", "-l"); // or whatever your command is
builder.redirectErrorStream(true);
Process proc = builder.start();
FWIW in my experience, you'd be better off trying to use the other Java program by starting its main method in your own program, than trying to wrestle with input/output streams etc., but that depends on what the other program does.

Passing a file as a command line argument and reading its lines

this is the code that i have found in the internet for reading the lines of a file and also I use eclipse and I passed the name of files as SanShin.txt in its argument field. but it will print :
Error: textfile.txt (The system cannot find the file specified)
Code:
public class Zip {
public static void main(String[] args){
try{
// Open the file that is the first
// command line parameter
FileInputStream fstream = new FileInputStream("textfile.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
String strLine;
//Read File Line By Line
while ((strLine = br.readLine()) != null) {
// Print the content on the console
System.out.println (strLine);
}
//Close the input stream
in.close();
}catch (Exception e){//Catch exception if any
System.err.println("Error: " + e.getMessage());
}
}
}
please help me why it prints this error.
thanks
...
// command line parameter
if(argv.length != 1) {
System.err.println("Invalid command line, exactly one argument required");
System.exit(1);
}
try {
FileInputStream fstream = new FileInputStream(argv[0]);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// Get the object of DataInputStream
...
> java -cp ... Zip \path\to\test.file
When you just specify "textfile.txt" the operating system will look in the program's working directory for that file.
You can specify the absolute path to the file with something like new FileInputStream("C:\\full\\path\\to\\file.txt")
Also if you want to know the directory your program is running in, try this:
System.out.println(new File(".").getAbsolutePath())
Your new FileInputStream("textfile.txt") is correct. If it's throwing that exception, there is no textfile.txt in the current directory when you run the program. Are you sure the file's name isn't actually testfile.txt (note the s, not x, in the third position).
Off-topic: But your earlier deleted question asked how to read a file line by line (I didn't think you needed to delete it, FWIW). On the assumption you're still a beginner and getting the hang of things, a pointer: You probably don't want to be using FileInputStream, which is for binary files, but instead use the Reader set of interfaces/classes in java.io (including FileReader). Also, whenever possible, declare your variables using the interface, even when initializing them to a specific class, so for instance, Reader r = new FileReader("textfile.txt") (rather than FileReader r = ...).

Categories

Resources