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

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

fix #8561 - fix restart on 6u45/7u21 (wrong call to Runtime.exec(String))

File size: 5.1 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.Shortcut;
21
22/**
23 * Restarts JOSM as it was launched. Comes from "restart" plugin, originally written by Upliner.
24 * <br/><br/>
25 * Mechanisms have been improved based on #8561 discussions and <a href="http://lewisleo.blogspot.jp/2012/08/programmatically-restart-java.html">this article</a>.
26 * @since 5857
27 */
28public class RestartAction extends JosmAction {
29
30 /**
31 * Constructs a new {@code RestartAction}.
32 */
33 public RestartAction() {
34 super(tr("Restart"), "restart", tr("Restart the application."),
35 Shortcut.registerShortcut("file:restart", tr("File: {0}", tr("Restart")), KeyEvent.VK_J, Shortcut.ALT_CTRL_SHIFT), false);
36 putValue("help", ht("/Action/Restart"));
37 putValue("toolbar", "action/restart");
38 Main.toolbar.register(this);
39 }
40
41 public void actionPerformed(ActionEvent e) {
42 try {
43 restartJOSM();
44 } catch (IOException ex) {
45 ex.printStackTrace();
46 }
47 }
48
49 /**
50 * Restarts the current Java application
51 * @throws IOException
52 */
53 public static void restartJOSM() throws IOException {
54 if (!Main.exitJosm(false)) return;
55 try {
56 // java binary
57 final List<String> cmd = new ArrayList<String>(Collections.singleton(System.getProperty("java.home") + "/bin/java"));
58 // vm arguments
59 for (String arg : ManagementFactory.getRuntimeMXBean().getInputArguments()) {
60 // if it's the agent argument : we ignore it otherwise the
61 // address of the old application and the new one will be in conflict
62 if (!arg.contains("-agentlib")) {
63 cmd.add(arg);
64 }
65 }
66 // program main and program arguments (be careful a sun property. might not be supported by all JVM)
67 String[] mainCommand = System.getProperty("sun.java.command").split(" ");
68 // program main is a jar
69 if (mainCommand[0].endsWith(".jar")) {
70 // if it's a jar, add -jar mainJar
71 cmd.add("-jar");
72 cmd.add(new File(mainCommand[0]).getPath());
73 } else {
74 // else it's a .class, add the classpath and mainClass
75 cmd.add("-cp");
76 cmd.add("\"" + System.getProperty("java.class.path") + "\"");
77 cmd.add(mainCommand[0]);
78 }
79 // finally add program arguments
80 cmd.addAll(Arrays.asList(Main.commandLineArgs));
81 // execute the command in a shutdown hook, to be sure that all the
82 // resources have been disposed before restarting the application
83 Runtime.getRuntime().addShutdownHook(new Thread() {
84 @Override
85 public void run() {
86 try {
87 Runtime.getRuntime().exec(cmd.toArray(new String[]{}));
88 } catch (IOException e) {
89 e.printStackTrace();
90 }
91 }
92 });
93 // exit
94 System.exit(0);
95 } catch (Exception e) {
96 // something went wrong
97 throw new IOException("Error while trying to restart the application", e);
98 }
99 }
100
101 /**
102 * Returns a new {@code ButtonSpec} instance that performs this action.
103 * @return A new {@code ButtonSpec} instance that performs this action.
104 */
105 public static ButtonSpec getRestartButtonSpec() {
106 return new ButtonSpec(
107 tr("Restart"),
108 ImageProvider.get("restart"),
109 tr("Restart the application."),
110 ht("/Action/Restart")
111 );
112 }
113
114 /**
115 * Returns a new {@code ButtonSpec} instance that do not perform this action.
116 * @return A new {@code ButtonSpec} instance that do not perform this action.
117 */
118 public static ButtonSpec getCancelButtonSpec() {
119 return new ButtonSpec(
120 tr("Cancel"),
121 ImageProvider.get("cancel"),
122 tr("Click to restart later."),
123 null /* no specific help context */
124 );
125 }
126
127 /**
128 * Returns default {@code ButtonSpec} instances for this action (Restart/Cancel).
129 * @return Default {@code ButtonSpec} instances for this action.
130 * @see #getRestartButtonSpec
131 * @see #getCancelButtonSpec
132 */
133 public static ButtonSpec[] getButtonSpecs() {
134 return new ButtonSpec[] {
135 getRestartButtonSpec(),
136 getCancelButtonSpec()
137 };
138 }
139}
Note: See TracBrowser for help on using the repository browser.