diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigClientsHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigClientsHandler.java
index d6c98c5229..91ac9726f0 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigClientsHandler.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigClientsHandler.java
@@ -11,7 +11,6 @@ import java.util.Set;
import net.i2p.router.startup.ClientAppConfig;
import net.i2p.router.startup.LoadClientAppsJob;
-import net.i2p.util.Log;
import org.mortbay.jetty.Server;
@@ -19,15 +18,19 @@ import org.mortbay.jetty.Server;
* Saves changes to clients.config or webapps.config
*/
public class ConfigClientsHandler extends FormHandler {
- private Log configClient_log;
private Map _settings;
- public ConfigClientsHandler() {
- configClient_log = ContextHelper.getContext(null).logManager().getLog(ConfigClientsHandler.class);
- }
-
@Override
protected void processForm() {
+ // set action for when CR is hit in a text input box
+ if (_action.length() <= 0) {
+ String url = getJettyString("pluginURL");
+ if (url != null && url.length() > 0)
+ _action = "Install Plugin";
+ else
+ _action = "Save Client Configuration";
+ }
+
if (_action.equals(_("Save Client Configuration"))) {
saveClientChanges();
return;
@@ -200,7 +203,7 @@ public class ConfigClientsHandler extends FormHandler {
return;
}
ClientAppConfig ca = clients.get(i);
- LoadClientAppsJob.runClient(ca.className, ca.clientName, LoadClientAppsJob.parseArgs(ca.args), configClient_log);
+ LoadClientAppsJob.runClient(ca.className, ca.clientName, LoadClientAppsJob.parseArgs(ca.args), _log);
addFormNotice(_("Client") + ' ' + _(ca.clientName) + ' ' + _("started") + '.');
}
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigClientsHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigClientsHelper.java
index a897f84e40..9dbf4de23a 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigClientsHelper.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigClientsHelper.java
@@ -43,11 +43,11 @@ public class ConfigClientsHelper extends HelperBase {
renderForm(buf, ""+cur, ca.clientName, false, !ca.disabled,
"webConsole".equals(ca.clientName) || "Web console".equals(ca.clientName),
ca.className + ((ca.args != null) ? " " + ca.args : ""), (""+cur).equals(_edit),
- true, false, false, true);
+ true, false, false, true, !ca.disabled);
}
if ("new".equals(_edit))
- renderForm(buf, "" + clients.size(), "", false, false, false, "", true, false, false, false, false);
+ renderForm(buf, "" + clients.size(), "", false, false, false, "", true, false, false, false, false, false);
buf.append("\n");
return buf.toString();
}
@@ -65,7 +65,7 @@ public class ConfigClientsHelper extends HelperBase {
String val = props.getProperty(name);
renderForm(buf, app, app, !"addressbook".equals(app),
"true".equals(val), RouterConsoleRunner.ROUTERCONSOLE.equals(app), app + ".war",
- false, false, false, false, false);
+ false, false, false, false, false, true);
}
}
buf.append("\n");
@@ -149,7 +149,7 @@ public class ConfigClientsHelper extends HelperBase {
boolean enableStop = !Boolean.valueOf(appProps.getProperty("disableStop")).booleanValue();
renderForm(buf, app, app, false,
"true".equals(val), false, desc.toString(), false, false,
- updateURL != null, enableStop, true);
+ updateURL != null, enableStop, true, true);
}
}
buf.append("\n");
@@ -160,7 +160,7 @@ public class ConfigClientsHelper extends HelperBase {
private void renderForm(StringBuilder buf, String index, String name, boolean urlify,
boolean enabled, boolean ro, String desc, boolean edit,
boolean showEditButton, boolean showUpdateButton, boolean showStopButton,
- boolean showDeleteButton) {
+ boolean showDeleteButton, boolean showStartButton) {
buf.append("
");
if (urlify && enabled) {
String link = "/";
@@ -183,7 +183,7 @@ public class ConfigClientsHelper extends HelperBase {
buf.append("disabled=\"true\" ");
}
buf.append("> | ");
- if ((!enabled) && !edit) {
+ if (showStartButton && (!ro) && !edit) {
buf.append("");
}
if (showEditButton && (!edit) && !ro)
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/PluginStarter.java b/apps/routerconsole/java/src/net/i2p/router/web/PluginStarter.java
index 1e14b8917d..cdeaaeb935 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/PluginStarter.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/PluginStarter.java
@@ -35,7 +35,7 @@ import org.mortbay.jetty.Server;
* @author zzz
*/
public class PluginStarter implements Runnable {
- private RouterContext _context;
+ protected RouterContext _context;
static final String PREFIX = "plugin.";
static final String ENABLED = ".startOnLoad";
private static final String[] STANDARD_WEBAPPS = { "i2psnark", "i2ptunnel", "susidns",
@@ -223,7 +223,8 @@ public class PluginStarter implements Runnable {
if (name != null && name.length() > 0)
NavHelper.unregisterApp(name);
- log.error("Stopping plugin: " + appName);
+ if (log.shouldLog(Log.WARN))
+ log.warn("Stopping plugin: " + appName);
return true;
}
@@ -426,7 +427,8 @@ public class PluginStarter implements Runnable {
}
try {
addPath(f.toURI().toURL());
- log.error("INFO: Adding plugin to classpath: " + f);
+ if (log.shouldLog(Log.WARN))
+ log.warn("INFO: Adding plugin to classpath: " + f);
} catch (Exception e) {
log.error("Plugin client " + clientName + " bad classpath element: " + f, e);
}
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/PluginStopper.java b/apps/routerconsole/java/src/net/i2p/router/web/PluginStopper.java
new file mode 100644
index 0000000000..2f29eddf27
--- /dev/null
+++ b/apps/routerconsole/java/src/net/i2p/router/web/PluginStopper.java
@@ -0,0 +1,40 @@
+package net.i2p.router.web;
+
+import net.i2p.router.RouterContext;
+import net.i2p.util.Log;
+
+/**
+ * Stop all plugins that are installed
+ *
+ * @since 0.7.13
+ * @author zzz
+ */
+public class PluginStopper extends PluginStarter {
+
+ public PluginStopper(RouterContext ctx) {
+ super(ctx);
+ }
+
+ @Override
+ public void run() {
+ stopPlugins(_context);
+ }
+
+ /**
+ * Stop all plugins
+ * (whether or not they were ever started)
+ *
+ * this shouldn't throw anything
+ */
+ static void stopPlugins(RouterContext ctx) {
+ Log log = ctx.logManager().getLog(PluginStopper.class);
+ for (String app : getPlugins()) {
+ try {
+ stopPlugin(ctx, app);
+ } catch (Throwable e) {
+ if (log.shouldLog(Log.WARN))
+ log.warn("Failed to stop plugin: " + app, e);
+ }
+ }
+ }
+}
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java b/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java
index ef5d2846c2..460db8d176 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java
@@ -190,9 +190,11 @@ public class RouterConsoleRunner {
List contexts = RouterContext.listContexts();
if (contexts != null) {
- if (PluginStarter.pluginsEnabled(contexts.get(0))) {
- t = new I2PAppThread(new PluginStarter(contexts.get(0)), "PluginStarter", true);
+ RouterContext ctx = contexts.get(0);
+ if (PluginStarter.pluginsEnabled(ctx)) {
+ t = new I2PAppThread(new PluginStarter(ctx), "PluginStarter", true);
t.start();
+ ctx.addShutdownTask(new PluginStopper(ctx));
}
}
}
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/WebAppStarter.java b/apps/routerconsole/java/src/net/i2p/router/web/WebAppStarter.java
index 048ef31cc6..8a146f5b1b 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/WebAppStarter.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/WebAppStarter.java
@@ -43,9 +43,17 @@ public class WebAppStarter {
/**
* add but don't start
+ * This is used only by RouterConsoleRunner, which adds all the webapps first
+ * and then starts all at once.
*/
static WebApplicationContext addWebApp(I2PAppContext ctx, Server server, String appName, String warPath, File tmpdir) throws IOException {
+ // Jetty will happily load one context on top of another without stopping
+ // the first one, so we remove any previous one here
+ try {
+ stopWebApp(server, appName);
+ } catch (Throwable t) {}
+
WebApplicationContext wac = server.addWebApplication("/"+ appName, warPath);
tmpdir.mkdir();
wac.setTempDirectory(tmpdir);
@@ -64,7 +72,7 @@ public class WebAppStarter {
}
/**
- * stop it
+ * stop it and remove the context
* @throws just about anything, caller would be wise to catch Throwable
*/
static void stopWebApp(Server server, String appName) {
@@ -74,6 +82,9 @@ public class WebAppStarter {
// false -> not graceful
wac.stop(false);
} catch (InterruptedException ie) {}
+ try {
+ server.removeContext(wac);
+ } catch (IllegalStateException ise) {}
}
/** see comments in ConfigClientsHandler */
diff --git a/apps/routerconsole/jsp/configclients.jsp b/apps/routerconsole/jsp/configclients.jsp
index 5cbdc73245..c9a668c797 100644
--- a/apps/routerconsole/jsp/configclients.jsp
+++ b/apps/routerconsole/jsp/configclients.jsp
@@ -30,7 +30,9 @@ button span.hide{
<% String prev = System.getProperty("net.i2p.router.web.ConfigClientsHandler.nonce");
if (prev != null) System.setProperty("net.i2p.router.web.ConfigClientsHandler.noncePrev", prev);
System.setProperty("net.i2p.router.web.ConfigClientsHandler.nonce", new java.util.Random().nextLong()+""); %>
- " />
+ " >
+ <% /* set hidden default */ %>
+
<%=intl._("Client Configuration")%>
<%=intl._("The Java clients listed below are started by the router and run in the same JVM.")%>
diff --git a/apps/routerconsole/jsp/configupdate.jsp b/apps/routerconsole/jsp/configupdate.jsp
index 017b7ba157..22432f60ac 100644
--- a/apps/routerconsole/jsp/configupdate.jsp
+++ b/apps/routerconsole/jsp/configupdate.jsp
@@ -25,7 +25,9 @@
<% String prev = System.getProperty("net.i2p.router.web.ConfigUpdateHandler.nonce");
if (prev != null) System.setProperty("net.i2p.router.web.ConfigUpdateHandler.noncePrev", prev);
System.setProperty("net.i2p.router.web.ConfigUpdateHandler.nonce", new java.util.Random().nextLong()+""); %>
- " />
+ " >
+ <% /* set hidden default */ %>
+
<%=intl._("Check for I2P and news updates")%>
|
@@ -59,6 +61,6 @@
<% } // if canInstall %>
|