Compile and run a Java program from another Java program - java

I am writing a program that takes the path to the input ".java" file with a main method. The program should then compile that file, and run it.
Let's say that the program I am trying to compile and run looks like this:
Main.java
public class Main {
public static void main(String[] args) {
System.out.println("Hello, world!");
}
}
The program that performs compilation and tries to run it:
Evaluator.java
/**
* Matches any .java file.
*/
private static final PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:**.java");
private static String path;
/**
* Program entry point. Obtains the path to the .java file as a command line argument.
*
* #param args One argument from the command line: path to the .java file.
* #throws Exception
*/
public static void main(String[] args) throws Exception {
if (args.length != 1) {
throw new IllegalArgumentException(
"Expected exactly one argument from the command line.");
}
if (!matcher.matches(Paths.get(args[0]))) {
throw new IllegalArgumentException(
String.format("File %s is not a valid java file.", args[0]));
}
// path is in a valid format
path = args[0];
// compile a program
compile();
// run a program
run();
}
/**
* Compiles a program.
*
* #throws Exception
*/
private static void compile() throws Exception {
System.out.println("Compiling the program ...");
Process p = Runtime.getRuntime().exec("javac " + path);
output("Std.In", p.getInputStream());
output("Std.Out", p.getErrorStream());
p.waitFor();
System.out.println("Program successfully compiled!\n");
}
/**
* Runs a program.
*
* #throws Exception
*/
private static void run() throws Exception {
System.out.println("Executing the program ...");
Process p = Runtime.getRuntime().exec("java " + getProgramName(path));
output("Std.In", p.getInputStream());
output("Std.Out", p.getErrorStream());
p.waitFor();
System.out.println("Program finished!");
}
private static void output(String stream, InputStream in) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(in, CS));
for (String line = reader.readLine(); line != null; line = reader.readLine()) {
System.out.println(String.format("%s: %s", stream, line));
}
}
private static String getProgramName(String path) {
return path.replace(".java", "");
}
}
My "Main.java" file is located in the project root. I am running the program with a command line argument "./Main.java". Doing so, compiles the program correctly and yields a new file "Main.class". However, the run method outputs as follows:
Std.Out: Error: Could not find or load main class ..Main
What should be the problem here?

Try to set to java process you're launching the correct working directory and then set the related classpath.
This should help.
Update
I suggest to use the method Runtime.getRuntime().exec(String command, String[] envp, File dir).
Last parameter dir is the process working directory.

The Problem here is you are passing argument
./Main.java
instead, you should pass Main.java as an argument else you need to change your getProgramName() method to return the Class name correctly.
Which will let you compile the program perfectly with javac command but problem happens when you need to run the program because that command should be
java Main
whereas you are trying to execute
java ./Main

Related

Encog Image Recognition, Invalid command Error

I am trying to run image recognition code in Encog framework.
This one
But I am having problems with the input. I am getting the following error
I am trying to get the picture into the program. I did it the following way.
public static void main(final String[] args) {
/*
if (args.length < 1) {
System.out
.println("Must specify command file. See source for format.");
} else {
*/
String string = "/Users/hehe/Downloads/Screenshot_2023-01-08_at_08.11.24-removebg-preview.png";
try {
final ImageNeuralNetwork program = new ImageNeuralNetwork();
program.execute(string);
} catch (final Exception e) {
e.printStackTrace();
}
Encog.getInstance().shutdown();
}
I commented first part of the code because I can't run this program in command line.
When I try to compile it like this
javac /Users/hehe/IdeaProjects/TestRencognition/src/main/java/ImageNeuralNetwork.java
I am getting error that the package org.encog does not exist

Execute Jar file in IDE and get the output (String)? [duplicate]

This question already has answers here:
Execute .jar file from a Java program
(10 answers)
Closed 6 years ago.
Is it possible to execute a Jar file on my IDE (IntelliJ) to get the output string for my own purpose on the project that I have?
I know that we can make system calls, but in this case I want to add a Jar file on my project and execute it whenever I want it.
For example: I have a project on IntelliJ, one of my classes (on this project) needs to get the output by running the Jar file (which is on my project).
On my terminal, I would do something like java -jar <jar_file>.jar <file>.asm and this would output a result to my terminal.
And I want to get that output from this command on my Java Class.
Your Jar file returns an output string, so I assume, it's main-method could look like:
public static void main(String[] args) {
System.out.println("output string");
}
And now, if you want to use this "output string" string in your own class, you could do it like this:
public class YourClass {
...
public String getOutputStringFromJar() {
String s = ""; // or = null;
try {
Process p = Runtime.getRuntime().exec("java -jar full/path/to/your/Jar.jar full/path/to/fibonacci.asm");// just like you would do it on your terminal
p.waitFor();
InputStream is = p.getInputStream();
byte b[] = new byte[is.available()];
is.read(b, 0, b.length); // probably try b.length-1 or -2 to remove "new-line(s)"
s = new String(b);
} catch (Exception ex) {
ex.printStackTrace();
}
return s;
}
...
}
Now you have the method, that returns the output string, and you can use it however you want, and you know how to execute a Jar file from your project whenever you want
Your ask is not precise, but if i understand what you're doing, you run the Mars.jar with .asm file in param, and you got an output like in the this link with Fibonacci numbers
and now you want to get the Fibonacci numbers in your program? if that is what you need, i would suggest you to decompile the jar to understand his content
When you do so, you'll see that the main class in the jar is like this
public class Mars {
public static void main(String[] args) {
new mars.MarsLaunch(args);
}
}
so simply when you add the jar to your class path, you need to do somthing like this
public static void main(String[] args) throws FileNotFoundException {
// this will redirect your system output to a file named output.txt
PrintStream out = new PrintStream(new FileOutputStream("output.txt"));
System.setOut(out);
String [] myAsmFile = {"C:/produits/Fibonacci.asm"};
new mars.MarsLaunch(myAsmFile);
// and then you can read the output.txt file
}
hope this help you

Java output stream to subprocess flush results in IOException

I have a subprocess receiving data from stdin line by line. Then it receives $X$ line, it stops reading input streams, performs internal task on it, then exits.
Now I wrote some tester for it:
public class MessageShowTester {
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws IOException {
Process p = Runtime.getRuntime().exec("java -jar \"/home/user/NetBeansProjects/MessageShow/dist/MessageShow.jar\"");
p.getOutputStream().write("Hi\n$X$\n".getBytes());
p.getOutputStream().flush();
}
}
As the result I receive IOException on p.getOutputStream().flush()line. Much stranger is that another application I use the same construction doesn't share such behavior.
There is a limited version of MessageShow as example, that fails same way on tester, but works well from IDE.
public class MessageShow {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
String message="";
String temp="";
while(true)
{
temp = new Scanner(System.in).nextLine();
if("$X$".equals(temp)) break;
message+=temp;
message+="\n";
}
JOptionPane.showMessageDialog(null, message);
}
}
Stack trace:
Exception in thread "main" java.io.IOException: Broken pipe
at java.io.FileOutputStream.writeBytes(Native Method)
at java.io.FileOutputStream.write(FileOutputStream.java:315)
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
at messageshowtester.MessageShowTester.main(MessageShowTester.java:23)
Java Result: 1
If the subprocess finishes quickly, the parent process may not yet have done the flush. In this situation, the pipe between the processes has already been closed on the subprocess side and you'll see
Exception in thread "main" java.io.IOException: Stream closed
or similar.
You shouldn't need the explicit flush. For passing a single line to a subprocess, consider a process parameter.
Less confident about what works and what not, but I have found that using
PrintWriter pw = new PrintWriter( p.getOutputStream() );
pw.println("hifile.dat");
pw.println("$X$");
pw.close();
succeeds in passing both lines to the subprocess.
In the subprocess,
Scanner scanner = new Scanner(System.in);
while(true){
temp = scanner.nextLine();
if("$X$".equals(temp)) break;
message+=temp;
}
is better than recreating a Scanner for each line, although it doesn't influence the fate of the subprocess.

What Are My args[]?

I've gotten ahead of myself and am taking a semester, which requires that I have knowledge of Java beyond what I've learned. I have no idea how I command like arguments are passed to the main argument, apart from "echo Java foo bar" through the command line
I'm trying to parse JSON through java; I hope that the code below is enough
This is my method:
public static void parseCrewWithListMapping(String filePath) {
ObjectMapper mapper = new ObjectMapper();
try {
List<Crew> crews = mapper.readValue(new File(filePath),
mapper.getTypeFactory().constructCollectionType(List.class, Crew.class));
for(Crew crew : crews) {
System.out.println(crew);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
And this is my main method trying to run this method.
public class CrewParsing {
public static void main(String[] args)
throws ParserConfigurationException, SAXException, IOException, XMLStreamException {
if(args.length < 1)
throw new RuntimeException("No argument exception");
System.out.println("Parsing Crew Names");
CrewParser.parseCrewWithListMapping(args[2]);
System.out.println("Finished\n\n");
}
}
All my files are in the correct places, I'm trying to recreate this:
public static void parseJSONWithListMapping(String filePath) {
ObjectMapper mapper = new ObjectMapper();
try {
List<Employee> employees = mapper.readValue(new File(filePath),
mapper.getTypeFactory().constructCollectionType(List.class, Employee.class));
for(Employee employee : employees){
System.out.println(employee);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Method:
public static void parseJSONWithListMapping(String filePath) {
ObjectMapper mapper = new ObjectMapper();
try {
List<Employee> employees = mapper.readValue(new File(filePath),
mapper.getTypeFactory().constructCollectionType(List.class, Employee.class));
for(Employee employee : employees){
System.out.println(employee);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
main method (which worked):
public class Practice1Test {
public static void main(String[] args)
throws ParserConfigurationException, SAXException, IOException, XMLStreamException {
if(args.length < 1)
throw new RuntimeException("No argument exception");
System.out.println("Parsing Crew Names");
CrewParser.parseJSONWithListMapping(args[2]);
System.out.println("Finished\n\n");
}
}
When passing args[2] as the arguments for parseJSONWithListMapping in the code that worked, I got my json results just fine.
But when I tried my code, the "no argument exception" was run, which I assume is telling me that there were no arguments passed.
What could be the problem? I really hope that this is enough detail ;_;
You're checking args.length < 1 and throwing the "No argument exception", but then you're trying to use args[2], which is the third command-line argument.
If you want the first, it's args[0], the second is args[1], and so on. If you require one argument, your args.length < 1 is correct and you'd use args[0]. If you require two arguments, you'd use args.length < 2 for the error and then use args[0] and args[1].
When you run your program from the command-line, you may pass in the list of arguments, such as:
java CrewParsing jsonPath1 jsonPath2 jsonPath3
If you are running from an IDE such as Eclipse, you are probably just clicking the Run or Debug and forgetting to enter in any arguments. In Eclipse - right-click your main class and when you hover over the Run(or Debug) as... choose run(debug) configuration. There is a tab for arguments, and you can enter them there. The program you are copying from probably has them set up already.
If you want some more information on arguments I find the Oracle command line tutorial explains it well: (All taken from link)
A Java application can accept any number of arguments from the command line. This allows the user to specify configuration information when the application is launched.
The user enters command-line arguments when invoking the application and specifies them after the name of the class to be run. For example, suppose a Java application called Sort sorts lines in a file. To sort the data in a file named friends.txt, a user would enter:
java Sort friends.txt
When an application is launched, the runtime system passes the command-line arguments to the application's main method via an array of Strings. In the previous example, the command-line arguments passed to the Sort application in an array that contains a single String: "friends.txt".
The Echo example displays each of its command-line arguments on a line by itself:
public class Echo {
public static void main (String[] args) {
for (String s: args) {
System.out.println(s);
}
}
}
The following example shows how a user might run Echo. User input is in italics.
java Echo Drink Hot Java
Drink
Hot
Java
//3 separate arguments are all printed out - args[0], args[1], args[2]
If you're still not sure what arguments you actually have, I would try printing out your arguments like that tutorial shows you.

How to call a class that accepts command line arguments?

I am not a good programmer. In school, I learned MATLAB. So i have no idea what I am doing.
I am working with the ThingMagic M6 reader. They have their own API. I wanted to create my own application to read the program. I want to use a sample program that they have supplied (since my program doesn't seem to work). However, the supplied program only accepts command line arguments. How do i change it so I can pass arguments to it in my code.
This is the supplied code: (at the command line I input tmr://10.0.0.101)
/**
* Sample program that reads tags for a fixed period of time (500ms)
* and prints the tags found.
*/
// Import the API
package samples;
import com.thingmagic.*;
public class read
{
static void usage()
{
System.out.printf("Usage: demo reader-uri <command> [args]\n" +
" (URI: 'tmr:///COM1' or 'tmr://astra-2100d3/' " +
"or 'tmr:///dev/ttyS0')\n\n" +
"Available commands:\n");
System.exit(1);
}
public static void setTrace(Reader r, String args[])
{
if (args[0].toLowerCase().equals("on"))
{
r.addTransportListener(r.simpleTransportListener);
}
}
static class TagReadListener implements ReadListener
{
public void tagRead(Reader r, TagReadData t) {
System.out.println("Tag Read " + t);
}
}
public static void main(String argv[])
{
System.out.println(argv.getClass().toString());
// Program setup
TagFilter target;
Reader r;
int nextarg;
boolean trace;
r = null;
target = null;
trace = false;
nextarg = 0;
if (argv.length < 1)
usage();
if (argv[nextarg].equals("-v"))
{
trace = true;
nextarg++;
System.out.println("Trace");
}
// Create Reader object, connecting to physical device
try
{
TagReadData[] tagReads;
r = Reader.create(argv[nextarg]);
if (trace)
{
setTrace(r, new String[] {"on"});
}
r.connect();
if (Reader.Region.UNSPEC == (Reader.Region)r.paramGet("/reader/region/id"))
{
r.paramSet("/reader/region/id", Reader.Region.NA);
}
r.addReadListener(new TagReadListener() );
// Read tags
tagReads = r.read(500);
// Print tag reads
for (TagReadData tr : tagReads)
System.out.println(tr.toString());
// Shut down reader
r.destroy();
}
catch (ReaderException re)
{
System.out.println("Reader Exception : " + re.getMessage());
}
catch (Exception re)
{
System.out.println("Exception : " + re.getMessage());
}
}
}
This is me trying to use it: (arg comes from a JTextField)
String[] argv = new String[1];
argv[0] = arg;
readOnceApp(argv);
I have a feeling there is a really simple answer to this problem, I just can't figure it out. I searched the internet for a few days and read books, and still can't figure it out. Any help is appreciated. Thank You.
edit: readOnceApp is one method I wrote. It is basically just the main method of the supplied code. I can include it, if it will help. I just didn't want to post too much code.
If you want to call the "main" method of a class from another class, do it like this:
String [] args = new String [1];
args[0]= "some param";
readOnceApp.main(args);
This is making the assumption that "readOnceApp" is the name of your class. (BTW, you should follow the convention of using capitalized class names, e.g. ReadOnceApp).
Hope this helps.

Categories

Resources