Commit df776c5e authored by Derek DeMoro's avatar Derek DeMoro Committed by derek

Added ability to work in development mode when developing plugins. This allows...

Added ability to work in development mode when developing plugins. This allows for hot swapping of classes as well as jsp compilation during runtime.

git-svn-id: http://svn.igniterealtime.org/svn/repos/wildfire/trunk@3847 b35dd754-fafc-0310-a699-88a17e54d16e
parent 3b48fcd3
...@@ -19,9 +19,9 @@ import java.net.MalformedURLException; ...@@ -19,9 +19,9 @@ import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.net.URLClassLoader; import java.net.URLClassLoader;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Collection;
/** /**
* ClassLoader for plugins. It searches the plugin directory for classes * ClassLoader for plugins. It searches the plugin directory for classes
...@@ -39,16 +39,13 @@ class PluginClassLoader { ...@@ -39,16 +39,13 @@ class PluginClassLoader {
private URLClassLoader classLoader; private URLClassLoader classLoader;
private final List<URL> list = new ArrayList<URL>(); private final List<URL> list = new ArrayList<URL>();
/** /**
* Constructs a plugin loader for the given plugin directory. * Constructs a plugin loader for the given plugin directory.
* *
* @param pluginDir the plugin directory.
* @throws SecurityException if the created class loader violates * @throws SecurityException if the created class loader violates
* existing security constraints. * existing security constraints.
*/ */
public PluginClassLoader(File pluginDir) throws SecurityException { public PluginClassLoader() throws SecurityException {
addDirectory(pluginDir);
} }
/** /**
...@@ -56,8 +53,10 @@ class PluginClassLoader { ...@@ -56,8 +53,10 @@ class PluginClassLoader {
* after adding the directory to make the change take effect. * after adding the directory to make the change take effect.
* *
* @param directory the directory. * @param directory the directory.
* @param developmentMode true if the plugin is running in development mode. This resolves classloader conflicts between the deployed plugin
* and development classes.
*/ */
public void addDirectory(File directory) { public void addDirectory(File directory, boolean developmentMode) {
try { try {
File classesDir = new File(directory, "classes"); File classesDir = new File(directory, "classes");
if (classesDir.exists()) { if (classesDir.exists()) {
...@@ -72,17 +71,25 @@ class PluginClassLoader { ...@@ -72,17 +71,25 @@ class PluginClassLoader {
if (jars != null) { if (jars != null) {
for (int i = 0; i < jars.length; i++) { for (int i = 0; i < jars.length; i++) {
if (jars[i] != null && jars[i].isFile()) { if (jars[i] != null && jars[i].isFile()) {
if (developmentMode) {
// Do not add plugin-pluginName.jar to classpath.
if (!jars[i].getName().equals("plugin-" + directory.getName() + ".jar")) {
list.add(jars[i].toURL());
}
}
else {
list.add(jars[i].toURL()); list.add(jars[i].toURL());
} }
} }
} }
} }
}
catch (MalformedURLException mue) { catch (MalformedURLException mue) {
Log.error(mue); Log.error(mue);
} }
} }
public Collection<URL> getURLS(){ public Collection<URL> getURLS() {
return list; return list;
} }
......
...@@ -186,12 +186,21 @@ public class PluginManager { ...@@ -186,12 +186,21 @@ public class PluginManager {
// Check to see if this is a child plugin of another plugin. If it is, we // Check to see if this is a child plugin of another plugin. If it is, we
// re-use the parent plugin's class loader so that the plugins can interact. // re-use the parent plugin's class loader so that the plugins can interact.
Element parentPluginNode = (Element)pluginXML.selectSingleNode("/plugin/parentPlugin"); Element parentPluginNode = (Element)pluginXML.selectSingleNode("/plugin/parentPlugin");
String pluginName = pluginDir.getName();
String webRootKey = pluginName + ".webRoot";
String classesDirKey = pluginName + ".classes";
String webRoot = System.getProperty(webRootKey);
String classesDir = System.getProperty(classesDirKey);
boolean inDevelopmentMode = webRoot != null && classesDir != null;
if (parentPluginNode != null) { if (parentPluginNode != null) {
String parentPlugin = parentPluginNode.getTextTrim(); String parentPlugin = parentPluginNode.getTextTrim();
// See if the parent is already loaded. // See if the parent is already loaded.
if (plugins.containsKey(parentPlugin)) { if (plugins.containsKey(parentPlugin)) {
pluginLoader = classloaders.get(getPlugin(parentPlugin)); pluginLoader = classloaders.get(getPlugin(parentPlugin));
pluginLoader.addDirectory(pluginDir); pluginLoader.addDirectory(pluginDir, inDevelopmentMode);
} }
else { else {
...@@ -233,37 +242,31 @@ public class PluginManager { ...@@ -233,37 +242,31 @@ public class PluginManager {
} }
// This is not a child plugin, so create a new class loader. // This is not a child plugin, so create a new class loader.
else { else {
pluginLoader = new PluginClassLoader(pluginDir); pluginLoader = new PluginClassLoader();
pluginLoader.addDirectory(pluginDir, inDevelopmentMode);
} }
// Check to see if development mode is turned on for the plugin. If it is, // Check to see if development mode is turned on for the plugin. If it is,
// configure dev mode. // configure dev mode.
Element developmentNode = (Element)pluginXML.selectSingleNode("/plugin/development");
PluginDevEnvironment dev = null;
if (developmentNode != null) {
Element webRoot = (Element)developmentNode.selectSingleNode(
"/plugin/development/webRoot");
Element classesDir = (Element)developmentNode.selectSingleNode(
"/plugin/development/classesDir");
PluginDevEnvironment dev = null;
if (inDevelopmentMode) {
dev = new PluginDevEnvironment(); dev = new PluginDevEnvironment();
String wrd = webRoot.getTextTrim(); File webRootDir = new File(webRoot);
File webRootDir = new File(wrd);
if (!webRootDir.exists()) { if (!webRootDir.exists()) {
// ok, let's try it relative from this plugin dir? // ok, let's try it relative from this plugin dir?
webRootDir = new File(pluginDir, wrd); webRootDir = new File(pluginDir, webRoot);
} }
if (webRootDir.exists()) { if (webRootDir.exists()) {
dev.setWebRoot(webRootDir); dev.setWebRoot(webRootDir);
} }
String cd = classesDir.getTextTrim(); File classes = new File(classesDir);
File classes = new File(cd);
if (!classes.exists()) { if (!classes.exists()) {
// ok, let's try it relative from this plugin dir? // ok, let's try it relative from this plugin dir?
classes = new File(pluginDir, cd); classes = new File(pluginDir, classesDir);
} }
if (classes.exists()) { if (classes.exists()) {
...@@ -327,7 +330,6 @@ public class PluginManager { ...@@ -327,7 +330,6 @@ public class PluginManager {
// If there a <adminconsole> section defined, register it. // If there a <adminconsole> section defined, register it.
Element adminElement = (Element)pluginXML.selectSingleNode("/plugin/adminconsole"); Element adminElement = (Element)pluginXML.selectSingleNode("/plugin/adminconsole");
if (adminElement != null) { if (adminElement != null) {
String pluginName = pluginDir.getName();
if(parentPluginNode != null){ if(parentPluginNode != null){
pluginName = parentPluginNode.getTextTrim(); pluginName = parentPluginNode.getTextTrim();
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment