source: josm/trunk/src/org/openstreetmap/josm/actions/RestartAction.java@ 6032

Last change on this file since 6032 was 5967, checked in by Don-vip, 11 years ago

see #8720, see #8733 - More checks and some debug info in RestartAction

File size: 6.0 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.actions;
3
4import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
5import static org.openstreetmap.josm.tools.I18n.tr;
6
7import java.awt.event.ActionEvent;
8import java.awt.event.KeyEvent;
9import java.io.File;
10import java.io.IOException;
11import java.lang.management.ManagementFactory;
12import java.util.ArrayList;
13import java.util.Arrays;
14import java.util.Collections;
15import java.util.List;
16
17import org.openstreetmap.josm.Main;
18import org.openstreetmap.josm.gui.HelpAwareOptionPane.ButtonSpec;
19import org.openstreetmap.josm.tools.ImageProvider;
20import org.openstreetmap.josm.tools.PlatformHookWindows;
21import org.openstreetmap.josm.tools.Shortcut;
22
23/**
24 * Restarts JOSM as it was launched. Comes from "restart" plugin, originally written by Upliner.
25 * <br/><br/>
26 * Mechanisms have been improved based on #8561 discussions and <a href="http://lewisleo.blogspot.jp/2012/08/programmatically-restart-java.html">this article</a>.
27 * @since 5857
28 */
29public class RestartAction extends JosmAction {
30
31 /**
32 * Constructs a new {@code RestartAction}.
33 */
34 public RestartAction() {
35 super(tr("Restart"), "restart", tr("Restart the application."),
36 Shortcut.registerShortcut("file:restart", tr("File: {0}", tr("Restart")), KeyEvent.VK_J, Shortcut.ALT_CTRL_SHIFT), false);
37 putValue("help", ht("/Action/Restart"));
38 putValue("toolbar", "action/restart");
39 Main.toolbar.register(this);
40 setEnabled(isRestartSupported());
41 }
42
43 public void actionPerformed(ActionEvent e) {
44 try {
45 restartJOSM();
46 } catch (IOException ex) {
47 ex.printStackTrace();
48 }
49 }
50
51 /**
52 * Determines if restarting the application should be possible on this platform.
53 * @return {@code true} if the mandatory system property {@code sun.java.command} is defined, {@code false} otherwise.
54 * @since 5951
55 */
56 public static boolean isRestartSupported() {
57 return System.getProperty("sun.java.command") != null;
58 }
59
60 /**
61 * Restarts the current Java application
62 * @throws IOException
63 */
64 public static void restartJOSM() throws IOException {
65 if (isRestartSupported() && !Main.exitJosm(false)) return;
66 try {
67 // java binary
68 final String java = System.getProperty("java.home") + File.separator + "bin" + File.separator +
69 (Main.platform instanceof PlatformHookWindows ? "java.exe" : "java");
70 if (!new File(java).isFile()) {
71 throw new IOException("Unable to find suitable java runtime at "+java);
72 }
73 final List<String> cmd = new ArrayList<String>(Collections.singleton(java));
74 // vm arguments
75 for (String arg : ManagementFactory.getRuntimeMXBean().getInputArguments()) {
76 // if it's the agent argument : we ignore it otherwise the
77 // address of the old application and the new one will be in conflict
78 if (!arg.contains("-agentlib")) {
79 cmd.add(arg);
80 }
81 }
82 // program main and program arguments (be careful a sun property. might not be supported by all JVM)
83 String[] mainCommand = System.getProperty("sun.java.command").split(" ");
84 // program main is a jar
85 if (mainCommand[0].endsWith(".jar")) {
86 // if it's a jar, add -jar mainJar
87 cmd.add("-jar");
88 cmd.add(new File(mainCommand[0]).getPath());
89 } else {
90 // else it's a .class, add the classpath and mainClass
91 cmd.add("-cp");
92 cmd.add("\"" + System.getProperty("java.class.path") + "\"");
93 cmd.add(mainCommand[0]);
94 }
95 // finally add program arguments
96 cmd.addAll(Arrays.asList(Main.commandLineArgs));
97 Main.info("Restart "+cmd);
98 // execute the command in a shutdown hook, to be sure that all the
99 // resources have been disposed before restarting the application
100 Runtime.getRuntime().addShutdownHook(new Thread() {
101 @Override
102 public void run() {
103 try {
104 Runtime.getRuntime().exec(cmd.toArray(new String[]{}));
105 } catch (IOException e) {
106 e.printStackTrace();
107 }
108 }
109 });
110 // exit
111 System.exit(0);
112 } catch (Exception e) {
113 // something went wrong
114 throw new IOException("Error while trying to restart the application", e);
115 }
116 }
117
118 /**
119 * Returns a new {@code ButtonSpec} instance that performs this action.
120 * @return A new {@code ButtonSpec} instance that performs this action.
121 */
122 public static ButtonSpec getRestartButtonSpec() {
123 return new ButtonSpec(
124 tr("Restart"),
125 ImageProvider.get("restart"),
126 tr("Restart the application."),
127 ht("/Action/Restart"),
128 isRestartSupported()
129 );
130 }
131
132 /**
133 * Returns a new {@code ButtonSpec} instance that do not perform this action.
134 * @return A new {@code ButtonSpec} instance that do not perform this action.
135 */
136 public static ButtonSpec getCancelButtonSpec() {
137 return new ButtonSpec(
138 tr("Cancel"),
139 ImageProvider.get("cancel"),
140 tr("Click to restart later."),
141 null /* no specific help context */
142 );
143 }
144
145 /**
146 * Returns default {@code ButtonSpec} instances for this action (Restart/Cancel).
147 * @return Default {@code ButtonSpec} instances for this action.
148 * @see #getRestartButtonSpec
149 * @see #getCancelButtonSpec
150 */
151 public static ButtonSpec[] getButtonSpecs() {
152 return new ButtonSpec[] {
153 getRestartButtonSpec(),
154 getCancelButtonSpec()
155 };
156 }
157}
Note: See TracBrowser for help on using the repository browser.