}\r
}\r
\r
+ @Override\r
+ public boolean unloadPlugin(String pluginId) {\r
+ try {\r
+ PluginState state = stopPlugin(pluginId);\r
+ if (!PluginState.STOPPED.equals(state)) {\r
+ return false;\r
+ }\r
+\r
+ PluginWrapper pluginWrapper = plugins.get(pluginId);\r
+ PluginDescriptor descriptor = pluginWrapper.getDescriptor();\r
+ List<PluginDependency> dependencies = descriptor.getDependencies();\r
+ for (PluginDependency dependency : dependencies) {\r
+ if (!unloadPlugin(dependency.getPluginId())) {\r
+ return false;\r
+ }\r
+ }\r
+\r
+ // remove the plugin\r
+ plugins.remove(pluginId);\r
+ resolvedPlugins.remove(pluginWrapper);\r
+ pathToIdMap.remove(pluginWrapper.getPluginPath());\r
+\r
+ // remove the classloader\r
+ if (pluginClassLoaders.containsKey(pluginId)) {\r
+ PluginClassLoader classLoader = pluginClassLoaders.remove(pluginId);\r
+ compoundClassLoader.removeLoader(classLoader);\r
+ try {\r
+ classLoader.close();\r
+ } catch (IOException e) {\r
+ log.error(e.getMessage(), e);\r
+ }\r
+ }\r
+ return true;\r
+ } catch (IllegalArgumentException e) {\r
+ // ignore not found exceptions because this method is recursive\r
+ }\r
+ return false;\r
+ }\r
+\r
/**\r
* Get plugin class loader for this path.\r
*/\r
*/
public PluginState stopPlugin(String pluginId);
+ /**
+ * Unload a plugin.
+ *
+ * @param pluginId
+ * @return true if the plugin was unloaded
+ */
+ public boolean unloadPlugin(String pluginId);
+
public PluginClassLoader getPluginClassLoader(String pluginId);
public <T> List<T> getExtensions(Class<T> type);
/*
* Copyright 2012 Decebal Suiu
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in compliance with
* the License. You may obtain a copy of the License in the LICENSE file, or at:
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
/**
* A class loader that has multiple loaders and uses them for loading classes and resources.
- *
+ *
* @author Decebal Suiu
*/
public class CompoundClassLoader extends ClassLoader {
loaders.add(loader);
}
+ public void removeLoader(ClassLoader loader) {
+ loaders.remove(loader);
+ }
+
@Override
public Class<?> findClass(String name) throws ClassNotFoundException {
for (ClassLoader loader : loaders) {
// try next
}
}
-
+
throw new ClassNotFoundException(name);
}
return url;
}
}
-
+
return null;
}
for (ClassLoader loader : loaders) {
resources.addAll(Collections.list(loader.getResources(name)));
}
-
+
return Collections.enumeration(resources);
}
-
+
}