java.lang.Object
net.i2p.router.web.PluginStarter
- All Implemented Interfaces:
Runnable
- Direct Known Subclasses:
PluginStopper
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprivate static classRunnable wrapper that updates every installed plugin.private static classSimple override to track whether a plugin's client is delayed and queued.Field Summary
Modifier and TypeFieldDescriptionprivate static Map<String, ClassLoader> The cached class loaders, by plugin name.protected RouterContextThe router context the plugins are started in.private static Map<String, Collection<SimpleTimer2.TimedEvent>> Delayed clients waiting for their plugins.private static final StringFile listing the enabled plugins.static final StringValue of the enabled property marking a plugin as deleted.static final StringSuffix of the property recording whether a plugin starts at load, false, true, or deleted.Plugin name to plugin version of plugins that do not work with Java 9+ Unmodifiable.Plugin name to plugin version of plugins that do not work with Jetty 9, but do not have a max-jetty-version=8.9999 set.static final StringDirectory under the router base holding the installed plugins.private static Map<String, ThreadGroup> The thread groups, by plugin name.private static Map<String, Collection<String>> The webapps each plugin provides.static final StringPrefix of every plugin property key.private static final String[]The themes that ship with the router.private static final String[]The webapps that ship with the router.Constructor Summary
ConstructorsConstructorDescriptionCreates the runner for the deferred plugin startup thread.Method Summary
Modifier and TypeMethodDescriptionprivate static voidAppend a URL to the system classpath at runtime, as described at http://jimlife.wordpress.com/2007/12/19/java-adding-new-classpath-at-runtime/private static URL[]classpathToURLArray(String classpath, String clientName, Log log) Convert a plugin classpath to URL array, for the plugin's own classloader.private static voidDeferred deletion of plugins that we failed to delete before.static booleandeletePlugin(RouterContext ctx, String appName) Uninstall a plugin: run its client apps' uninstall commands, unregister its themes (falling back to the default theme if it is the current one), remove its directory and drop its plugins.config entries.static voiddisablePlugin(String appName) Disable in plugins.config.All installed plugins whether enabled or not, DOES include plugins marked as deleted.The signing keys from all the plugins.All installed plugins whether enabled or not, but does NOT include plugins marked as deleted.private static Stringgettext(String s, Object o, I2PAppContext ctx) Translate a string.private static booleanisClientThreadRunning(String pluginName, RouterContext ctx) Returnstrueif one or more client threads are running in a given plugin.static booleanisPluginEnabled(String appName) Is the plugin enabled in plugins.config? Default true.static booleanisPluginRunning(String pluginName, RouterContext ctx) Is any part of the plugin still up? Client threads, console webapps, queued client apps and registered client apps all count.protected static booleanisPluginRunning(String pluginName, RouterContext ctx, Server s) Is any part of the plugin still up? Client threads, console webapps, queued client apps and registered client apps all count.private static Stringngettext(String s, String p, int n, I2PAppContext ctx) Translate a string.private static voidpluginIncompatible(Log log, RouterContext ctx, String appName, String detail, String userMessage) Reject a plugin with incompatible requirements: log, disable, and throw.static PropertiesRead the plugins.config file, this auto-adds a property for every dir in the plugin directory.static PropertiespluginProperties(I2PAppContext ctx, String appName) Read the plugin.config file for a single plugin.static booleanHas the user allowed plugins to be started at all?voidrun()Startup pass: apply deferred deletions, optionally update plugins, then start every plugin marked enabled in plugins.config.private static voidrunClientApps(RouterContext ctx, File pluginDir, List<ClientAppConfig> apps, String action) Start the client apps of a plugin.static booleanstartPlugin(RouterContext ctx, String appName) Start a plugin: extract a pending update, enforce the min/max I2P, Java and Jetty version requirements, register its themes, client apps, console webapps, translation jars and summary bar link.(package private) static voidStart every plugin whose plugins.config entry is "true", skipping any that an update already started.static booleanstopPlugin(RouterContext ctx, String appName) Stop a plugin: shut down its client apps and console webapps, drop its summary bar link, and release its thread group, pending timers and ClassLoader cache.protected static booleanstopPlugin(RouterContext ctx, Server s, String appName) Stop a plugin using an already-located console server, so this also works during shutdown after the server has been unregistered.static voidstorePluginProperties(Properties props) Write the plugins.config file.static StringstripHTML(Properties props, String key) Like inDataHelperbut doesn't convert null to "" There's a lot worse things a plugin could do but...static voidupdateAll(RouterContext ctx) Starts the plugin update on a daemon thread, so the caller does not block.private static voidupdateAll(RouterContext ctx, boolean delay) Fetches and restarts the installed plugins in the calling thread.
Field Details
_context
The router context the plugins are started in.CONFIG_FILE
File listing the enabled plugins.- See Also:
PREFIX
ENABLED
Suffix of the property recording whether a plugin starts at load, false, true, or deleted.- See Also:
DELETED
Value of the enabled property marking a plugin as deleted.- See Also:
PLUGIN_DIR
Directory under the router base holding the installed plugins.- See Also:
STANDARD_WEBAPPS
The webapps that ship with the router.STANDARD_THEMES
The themes that ship with the router.pluginThreadGroups
The thread groups, by plugin name._pendingPluginClients
Delayed clients waiting for their plugins._clCache
The cached class loaders, by plugin name.pluginWars
The webapps each plugin provides.jetty9Blacklist
java9Blacklist
Constructor Details
PluginStarter
Creates the runner for the deferred plugin startup thread.- Parameters:
ctx- router context supplying the config dir, logging and console server
Method Details
pluginsEnabled
Has the user allowed plugins to be started at all?- Parameters:
ctx- context to readrouter.enablePluginsfrom- Returns:
- false only if the user has explicitly disabled plugins
run
updateAll
Starts the plugin update on a daemon thread, so the caller does not block.- Parameters:
ctx- router context to check and fetch the plugins with
updateAll
Fetches and restarts the installed plugins in the calling thread.- Parameters:
ctx- the router context, used for the update manager and router statedelay- true to first wait for the router to be running, up to 30 minutes, and for the scheduled update delay
startPlugins
Start every plugin whose plugins.config entry is "true", skipping any that an update already started. Failures are logged, never thrown.- Parameters:
ctx- router context supplying the config dir, logging and console server
deferredDeletePlugins
Deferred deletion of plugins that we failed to delete before.- Parameters:
ctx- the router context, used for the log
pluginIncompatible
private static void pluginIncompatible(Log log, RouterContext ctx, String appName, String detail, String userMessage) throws Exception Reject a plugin with incompatible requirements: log, disable, and throw.- Parameters:
log- the plugin's loggerctx- the router contextappName- the plugin directory namedetail- the technical reason for the loguserMessage- the message for the thrown exception- Throws:
Exception- always, carrying the user message
startPlugin
Start a plugin: extract a pending update, enforce the min/max I2P, Java and Jetty version requirements, register its themes, client apps, console webapps, translation jars and summary bar link.- Parameters:
ctx- router context supplying the config dir, logging and console serverappName- plugin directory name under $I2P/plugins- Returns:
- true on success, or false if the plugin directory is missing
- Throws:
Exception- just about anything, caller would be wise to catch Throwable
stopPlugin
Stop a plugin: shut down its client apps and console webapps, drop its summary bar link, and release its thread group, pending timers and ClassLoader cache.- Parameters:
ctx- router context supplying the config dir, logging and console serverappName- plugin directory name under $I2P/plugins- Returns:
- true on success
- Throws:
Exception- just about anything, caller would be wise to catch Throwable
stopPlugin
Stop a plugin using an already-located console server, so this also works during shutdown after the server has been unregistered.- Parameters:
ctx- router context supplying the config dir, logging and the PortMappers- the Jetty server holding the console contexts, null if not runningappName- plugin directory name under $I2P/plugins- Returns:
- true on success
- Throws:
Exception- just about anything, caller would be wise to catch Throwable
deletePlugin
Uninstall a plugin: run its client apps' uninstall commands, unregister its themes (falling back to the default theme if it is the current one), remove its directory and drop its plugins.config entries.- Parameters:
ctx- router context supplying the config dir and loggingappName- plugin directory name under $I2P/plugins- Returns:
- true on success - caller should call
stopPlugin(RouterContext, String)first - Throws:
Exception- just about anything, caller would be wise to catch Throwable
pluginProperties
Read the plugin.config file for a single plugin.- Parameters:
ctx- context to resolve the config dir holding the pluginappName- plugin directory name under $I2P/plugins- Returns:
- non-null, empty if plugin.config is missing or unreadable
pluginProperties
Read the plugins.config file, this auto-adds a property for every dir in the plugin directory.- Returns:
- non-null, empty if plugins.config is missing or unreadable
isPluginEnabled
Is the plugin enabled in plugins.config? Default true.- Parameters:
appName- plugin directory name under $I2P/plugins- Returns:
- whether plugin enabled
disablePlugin
Disable in plugins.config.- Parameters:
appName- plugin directory name under $I2P/plugins
getPlugins
getAllPlugins
getPluginKeys
The signing keys from all the plugins.- Parameters:
ctx- context supplying the config dir holding each plugin.config- Returns:
- Map of key to keyname Last one wins if a dup (installer should prevent dups)
storePluginProperties
Write the plugins.config file.- Parameters:
props- written to plugins.config, converted to OrderedProperties if needed
runClientApps
private static void runClientApps(RouterContext ctx, File pluginDir, List<ClientAppConfig> apps, String action) throws Exception Start the client apps of a plugin.- Parameters:
ctx- the router context, used for the logs and client appspluginDir- the plugin's installation directory, its name is the plugin nameapps- the client app configs to run, in orderaction- "start" or "stop" or "uninstall"- Throws:
Exception- just about anything if an app has a delay less than zero, caller would be wise to catch Throwable If no apps have a delay less than zero, it shouldn't throw anything
isPluginRunning
Is any part of the plugin still up? Client threads, console webapps, queued client apps and registered client apps all count.- Parameters:
pluginName- plugin directory name under $I2P/pluginsctx- router context supplying the client app manager and logging- Returns:
- whether plugin running
isPluginRunning
Is any part of the plugin still up? Client threads, console webapps, queued client apps and registered client apps all count.- Parameters:
pluginName- plugin directory name under $I2P/pluginsctx- router context supplying the client app manager and loggings- the Jetty server holding the console contexts, null to skip the webapp check- Returns:
- whether plugin running
isClientThreadRunning
Returnstrueif one or more client threads are running in a given plugin.- Parameters:
pluginName- plugin directory name whose thread group is inspectedctx- router context, for the debug log of the threads found- Returns:
- true if running
classpathToURLArray
Convert a plugin classpath to URL array, for the plugin's own classloader. Perhaps there's an easy way to useThread.setContextClassLoader(ClassLoader), but I don't see how to make it magically get used for everything.- Parameters:
classpath- the plugin classpath, comma-separated absolute file pathsclientName- the plugin client name, used in the log messageslog- the log to report invalid classpath elements to- Returns:
- null if no valid elements
addPath
Append a URL to the system classpath at runtime, as described at http://jimlife.wordpress.com/2007/12/19/java-adding-new-classpath-at-runtime/- Parameters:
u- the URL to append to the system classloader's classpath- Throws:
ClassCastException- in Java 9Exception- if the reflective lookup or invocation of the classloader's addURL method fails
stripHTML
Like inDataHelperbut doesn't convert null to "" There's a lot worse things a plugin could do but...- Parameters:
props- plugin properties to read fromkey- plugin.config key to look up- Returns:
- the value with markup replaced by spaces, or null if not set
gettext
Translate a string.- Parameters:
s- the message key to translateo- optional argument for the message, null if nonectx- the app context supplying the locale- Returns:
- the translated text for s
ngettext
Translate a string.- Parameters:
s- the singular form of the messagep- the plural form of the messagen- the count selecting the singular or plural formctx- the app context supplying the locale- Returns:
- the translated form matching the count