Java – ide style program running
My goal
I'm trying to create a java program that users can choose from any of their computers Class or Jar file Then my program will pop up a jinternalframe with jeditor pane as the console to capture any console output of the user program When the user's program closes (call system. Exit (int status);) My program can't close with it My program may also have a function, such as the button to stop the user program immediately and other functions of the IDE My program doesn't need to compile java code, just run it Class and Jar file
My experience
I have made a small test version of this program, in which I get two specific files from a package and let the user click one of the two buttons, each button represents one of the two programs Pressing the button calls the following method:
private void run(Class runnable) { java.lang.reflect.Method[] m = runnable.getmethods(); boolean hasMain = false; for (int i = 0; i < m.length; i++) { if (m[i].getName().equals("main") && m[i].getParameterTypes()[0].isArray() && m[i].getParameterTypes()[0].getName().contains("java.lang.String")) try { Object invoke = m[i].invoke(null,(Object)globalArgs); hasMain = true; hub.setExtendedState(Hub.ICONIFIED); numPrograms++; } catch (Throwable t) { java.util.logging.Logger.getLogger(Hub.class.getName()).log(java.util.logging.Level.SEVERE,null,t); javax.swing.JOptionPane.showMessageDialog(null,"Could not run " + runnable.getName(),"Error in invocation",javax.swing.JOptionPane.ERROR_MESSAGE); } finally { break; } } if (!hasMain) javax.swing.JOptionPane.showMessageDialog(null,runnable.getName() + " does not have a public static main method that\nreturns void and takes in an array of Strings","No main method",javax.swing.JOptionPane.ERROR_MESSAGE); }
This method successfully calls the main method of the program and runs a copy of the program However, when any program that this hub has started calls system The hub will also shut down when the exit (int status) command In addition, I have no clue how to capture console output
My question
Is there anyone who has any experience or suggestions they are willing to share to help me make a fully functional program that can
>Open and run a compiled Java file (remember that. Jar files may have multiple classes with main (string [] args) methods) > catch system exit(int status); So that the hub program can handle the exit of internal programs > capture new Java io. PrintStream(). Println (object o) and similar calls and put their output in jeditorpane > press a button to stop the internal program running > all jframes used by the internal program may enter jinternalframes and put them in jdesktoppane
Solution
If you don't want other programs (through its main method call) to be able to shut down the JVM you're running, I can see three options:
1. Use securitymanager
Set up securitymanager to prevent system Exit call:
public class Test { public static void main(String args[]) { SecurityManager sm = System.getSecurityManager(); System.setSecurityManager(new SecurityManager() { @Override public void checkExit(int status) { throw new SecurityException("Client program exited."); } }); try { System.out.println("hello"); System.exit(0); System.out.println("world"); } catch (SecurityException se) { System.out.println(se.getMessage()); } } }
Print:
hello Client program exited.
This may be the best solution This is how the application server prevents any servlet from terminating the entire server
2. Separate JVM
Use process builder, for example, to run other programs in a separate JVM
import java.io.*; public class Test { public static void main(String args[]) throws IOException { ProcessBuilder pb = new ProcessBuilder("java","other.Program"); pb.redirectErrorStream(); Process p = pb.start(); InputStream is = p.getInputStream(); int ch; while ((ch = is.read()) != -1) System.out.print((char) ch); is.close(); System.out.println("Client program done."); } }
3. Use shutdown hooks instead
Instead of disabling the termination of the JVM, add a close hook to clean up the hub and exit normally (this option may only make sense if you run one "external" program at a time.)
import java.io.*; public class Test { public static void main(String args[]) throws IOException { Runtime.getRuntime().addShutdownHook(new Thread() { public void run() { System.out.println("Uninitializing hub..."); System.out.println("Exiting gracefully."); } }); // Run client program System.out.println("Running... running... running..."); System.exit(0); } }
Print:
Running... running... running... Uninitializing hub... Exiting gracefully.