简体   繁体   中英

Can you run a java class from within a java program?

I have been creating a program that writes and run java classes. So far I have been able to write a "Runable.java" class but not able to run it. I have tried to run a "runjava.bat" and get the .bat to run the "Runable.java" class but I keep getting a " Error: Could not find or load main class application.Runable.class ". I was wondering what I am doing wrong or if there is a better way to go about running a java class from within a java program?

Here is my code(Simplify Slightly):

Main.java:

package application;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;

import javafx.application.Platform;
import javafx.stage.FileChooser;


public class Main {
final static String Program =
        "package application;\n"
        + "public class Runable {\n"
        + "public static void main(String[] args) {\n"
        + "System.out.println(\"Hello\");\n"
        + "}\n"
        + "}\n";

public static void main(String[] args) throws IOException {
    Scanner s = new Scanner(System.in);
    while(true){
    System.out.println("State a comand.");
    String Command = s.nextLine();
    if (Command.equalsIgnoreCase("Write") || Command.equalsIgnoreCase("Save")){
         FileChooser fileChooser = new FileChooser();

         //Set extension filter
         FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("TXT files (*.txt)", "*.txt");
         fileChooser.getExtensionFilters().add(extFilter);

         //Show save file dialog
         File file = new File("src/application/Runable.class");

         if(file != null){
             SaveFile(Program, file);
         }

    }
    else if (Command.equalsIgnoreCase("Run") || Command.equalsIgnoreCase("Play")){
        ProcessBuilder builder = new ProcessBuilder(
                "src/runjava.bat");
            builder.redirectErrorStream(true);
            Process p = builder.start();
            BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
            String line;
            while (true) {
                line = r.readLine();
                if (line == null) { break; }
                System.out.println(line);
            }
    }
    else if (Command.equalsIgnoreCase("End") || Command.equalsIgnoreCase("Exit")){
        Platform.exit();
    }
    else{
        System.err.println("Command not recognized.");
        System.err.println("Please try again.");
    }
    }

}

private static void SaveFile(String content, File file){
    try {
        FileWriter fileWriter = null;

        fileWriter = new FileWriter(file);
        fileWriter.write(content);
        fileWriter.close();
    } catch (IOException ex) {
        Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
    }

}


}

runjava.bat:

javac "src\application\Runable.java"
java application.Runable.class

and Runable.java if you didn't get it from the Main.java:

package application;
public class Runable {
public static void main(String[] args) {
System.out.println("Hello");
}
}

The java command expects a class name, not a filename. Unless your class is called "class" in the package "application.Runable" (which it isn't) you probably wanted to use:

java application.Runable

Because you can't execute a .java file like that. You must first compile it to get a .class file, and change the code that executes the class to point to Runable.class

The reason it is not running, is because the .java file is the code you type, and the .class file is the compiled version of the code that Java Virtual Machine executes.

Another solution to compile and run the program compared to executing the .bat file is to use the javax.tools API or another library based off of it. I have found InMemoryJavaCompiler library that makes it easy to compile and run the programs. This approach means that the program will run on the same JVM as your UI which may be helpful.

The following code shows how you might invoke the program using the library.

try{
    Class<?> clazz = InMemoryJavaCompiler.compile("apllication.Runable", Program);
    clazz.getMethod("main", String[].class).invoke(null, new String[0]);
}catch(Exception e){
    e.printStackTrace();
}

In your Main.java 's "Run" block, you should have

ProcessBuilder builder = new ProcessBuilder("runjava.bat");

In your runjava.bat , you should have (as immibis said)

javac -d . src/application/Runable.java
java application.Runable

** not Runable.class in the second line.

And runjava.bat should be placed in parallel with the parent folder of application\\ but not the src\\application folder. In other words, you should have something like classes\\runjava.bat , classes\\application\\Main.class and classes\\application\\Runable.class . Hope it helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM