我正在尝试制作一个Java程序,用户可以从其计算机中选择任何.class
或.jar
文件。然后,我的程序将弹出一个JInternalFrame
,其中包含JEditorPane
作为控制台,捕获用户程序的任何控制台输出。当用户的程序关闭(调用System.exit(int status);
)时,我的程序不能随之关闭。我的程序可能还有一个功能,如立即停止用户程序的按钮和IDE的其他功能。我的程序不需要编译Java代码,只需运行.class
和.jar
文件。
我已经制作了这个程序的一个小测试版本,其中我从一个包中获得了两个特定文件,并让用户单击两个按钮中的一个,每个按钮代表两个程序中的一个。按一下按钮会调用以下方法:
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);
}
此方法成功调用程序的main方法并运行所述程序的副本。但是,当此集线器已启动的任何程序调用{{1}}命令时,集线器也会关闭。另外,我对如何捕获控制台输出没有丝毫的线索。
是否有人有任何经验或建议,他们愿意分享这些经验或建议,以帮助我制作一个功能齐全的计划......
System.exit(int status)
个文件可能包含多个具有.jar
方法的类)main(String[] args)
以便中心程序处理内部程序退出System.exit(int status);
和类似的来电并将其输出放在new java.io.PrintStream().println(Object o)
JEditorPane
都放入JFrame
并将其放入JInternalFrame
答案 0 :(得分:7)
如果您不希望其他程序(通过它的主方法调用)能够关闭您正在运行的JVM,那么我有三个选项:
设置 SecurityManager ,以防止System.exit
来电:
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());
}
}
}
<强>打印强>:
hello
Client program exited.
这可能是最好的解决方案。这是应用程序服务器阻止任意servlet终止整个服务器的方式。
使用例如ProcessBuilder
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.");
}
}
不要禁止终止JVM,而是添加关闭钩子来清理“集线器”并正常退出。 (如果你一次运行一个“外部”程序,这个选项可能才有意义。)
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);
}
}
<强>打印强>
Running... running... running...
Uninitializing hub...
Exiting gracefully.