我已经创建了一个java应用程序并将其打包到一个可执行的jar文件中。现在,用户可以通过以下两种方式之一启动该程序:
通过在命令提示符下执行以下命令从命令提示符启动:
java -jar“MyJar.jar”
双击该jar文件。
我希望我的客户采用第二种方法,因为它比第一种方法容易得多。但第二种方法的问题是如何在应用程序完成之前停止它?
这是一个命令行应用程序。
当用户双击jar文件时,不会出现命令提示符窗口。那么在这种情况下,Ctrl + c会工作吗?
答案 0 :(得分:11)
停止(退出)应用程序应该在应用程序内部。无论是命令行还是基于GUI,应用程序开发人员都应该编写代码来退出它(例如,在命令行应用程序中,您可能有Press 5 to exit
,Press Esc to Exit
等)并在应用程序中使用GUI,您必须编写代码以在窗口关闭时退出,或者EXIT
按钮(或其他,取决于您的应用程序)
Ctrl + C
杀死了该应用程序。这是不正常退出。对于具有GUI的应用程序,用户通常(在Windows中)转到任务管理器并结束该过程(在其他操作系统中的方式类似)
但这些是异常退出 - 当用户想要杀死应用程序时,例如,应用程序不再响应。正常退出应由应用程序提供(因此由程序员 - 您提供)
答案 1 :(得分:5)
我遇到了类似的问题。我有一些Java程序基本上是长期运行的守护程序进程。能够阻止它们并反弹(重新启动)它们真是太好了。
我用了两种方法。两者都有优点和缺点。一种是设置一个信号处理程序,通过在你的程序的某个类中放置这样的函数(在我的程序中,它使用main方法)。
import sun.misc.Signal;
import sun.misc.SignalHandler;
...
private static boolean stopNow = false;
private static boolean restartNow = false;
...
private static void handleSignals() {
try {
Signal.handle(new Signal("TERM"), new SignalHandler() {
// Signal handler method for CTRL-C and simple kill command.
public void handle(Signal signal) {
MyClass.stopNow = true;
}
});
}
catch (final IllegalArgumentException e) {
logger.warn("No SIGTERM handling in this instance.");
}
try {
Signal.handle(new Signal("INT"), new SignalHandler() {
// Signal handler method for kill -INT command
public void handle(Signal signal) {
MyClass.stopNow = true;
}
});
}
catch (final IllegalArgumentException e) {
logger.debug("No SIGINT handling in this instance.");
}
try {
Signal.handle(new Signal("HUP"), new SignalHandler() {
// Signal handler method for kill -HUP command
public void handle(Signal signal) {
MyClass.restartNow = true;
}
});
}
catch (final IllegalArgumentException e) {
logger.warn("No SIGHUP handling in this instance.");
}
}
这对我们的生产起到了很好的作用。你需要一个真正的Sun JRE才能工作;一个典型的Linux发行版附带的那个没有Signal信号。它在Windows上运行正常,但是你没有得到HUP信号。你确实需要一个快捷方式或一个shellcript来启动这个东西。
另外,请记住,信号处理是一个很大的问题。不要试图在信号处理程序中做很多事情。您可以看到我的示例代码只是设置静态标志。程序的其他部分检测到标志已更改,然后关闭。我本可以在信号处理程序中尝试更复杂的代码,但我不想承担QA负担。
另一种方法是将程序结构化为Servlet。在这种情况下,您将编写一个扩展HttpServlet的类。使用启动工作线程的方法覆盖Servlet.init。同样,使用一种关闭自己的方法覆盖Servlet.destroy。
然后,您可以使用像Tomcat这样的Java EE容器服务器来管理启动和停止。
答案 2 :(得分:2)
如果您的程序是控制台模式程序并且正在执行输出,则Ctrl-C应该能够将其终止。
如果是GUI程序,您需要给它一个退出按钮,或者至少将EXIT_ON_CLOSE
设置为主JFrame的defaultCloseOperation
。
答案 3 :(得分:1)
ctrl + alt + suppr - >杀掉javaw.exe? :P
或者您必须使用停止按钮呈现用户界面(请参阅摆动等)
答案 4 :(得分:1)
这取决于用户界面。如果它是一个Swing应用程序,那么你可以在主框架上设置DefaulCloseOperation(JFrame.EXIT_ON_CLOSE)。如果它是一个控制台应用程序并且用户正在与它进行交互,那么您要求用户输入一个值,表明他们想要停止该应用程序。如果yoy根本没有与用户交互,那么ctrl-c将必须工作。
答案 5 :(得分:0)
是GUI应用程序还是命令行。
在第一种情况下,只处理窗口关闭事件。在第二种情况下,例如CTRL + C
答案 6 :(得分:0)
这取决于它是什么类型的应用程序?
是摆动应用吗?如果是这样,那么当用户点击“关闭”按钮时,您的应用就应该处理。有一种行为。 JFrame.close()
如果它不是摇摆应用程序,那么ctrl + c将起作用。
答案 7 :(得分:0)
“这是一个命令行应用程序”你说..你可以这样做,以便当用户点击按钮(比如esc)时,他可以编写短命令退出,重新启动等。
您可以使用KeyListener执行此操作。当ESC命中时(比如你希望用户点击的那个按钮),你在System.in上使用Scanner,你会做一个System.exit(0);如果输入是“退出”。
答案 8 :(得分:0)
我使用套接字连接来启用运行实例的终止。
//send kill signal to running instance, if any
try {
new Socket("localhost", 4000).getInputStream().read(); //block until its done
} catch (Exception e) { //if no one is listening, we're the only instance
}
//start kill listener for self
new Thread() {
@Override
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(4000);
serverSocket.accept();
//do cleanup here
serverSocket.close();
} catch (Exception e) {
}
System.exit(0);
}
}.start();
答案 9 :(得分:0)
你可以使用这个:exit()
可以在虚拟机完全停止之前预定义所有操作,这样您就可以保存数据并执行所有操作以防止数据丢失。 我不确定这是一个好方法,因为我刚刚开始学习Java,但它似乎有效。