Commit fae2712b authored by Gaston Dombiak's avatar Gaston Dombiak Committed by gato

Plugin that fails to be unloaded is not loaded again. JM-1092

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/trunk@8661 b35dd754-fafc-0310-a699-88a17e54d16e
parent eb94fbb8
...@@ -563,17 +563,40 @@ public class PluginManager { ...@@ -563,17 +563,40 @@ public class PluginManager {
catch (Exception e) { catch (Exception e) {
Log.error(e); Log.error(e);
} }
plugins.remove(pluginName); // Try to remove the folder where the plugin was exploded. If this works then
pluginDirs.remove(plugin); // the plugin was successfully removed. Otherwise, some objects created by the
classloaders.remove(plugin); // plugin are still in memory.
File dir = new File(pluginDirectory, pluginName);
// See if this is a child plugin. If it is, we should unload // Give the plugin 2 seconds to unload.
// the parent plugin as well. try {
if (childPluginMap.containsKey(plugin)) { Thread.sleep(2000);
unloadPlugin(childPluginMap.get(plugin)); // Ask the system to clean up references.
System.gc();
int count = 0;
while (!deleteDir(dir) && count < 5) {
Log.warn("Error unloading plugin " + pluginName + ". " + "Will attempt again momentarily.");
Thread.sleep(8000);
count++;
// Ask the system to clean up references.
System.gc();
}
} catch (InterruptedException e) {
Log.error(e);
}
if (!dir.exists()) {
plugins.remove(pluginName);
pluginDirs.remove(plugin);
classloaders.remove(plugin);
// See if this is a child plugin. If it is, we should unload
// the parent plugin as well.
if (childPluginMap.containsKey(plugin)) {
unloadPlugin(childPluginMap.get(plugin));
}
childPluginMap.remove(plugin);
firePluginDestroyedEvent(pluginName, plugin);
} }
childPluginMap.remove(plugin);
firePluginDestroyedEvent(pluginName, plugin);
} }
private void firePluginDestroyedEvent(String name, Plugin plugin) { private void firePluginDestroyedEvent(String name, Plugin plugin) {
...@@ -874,21 +897,8 @@ public class PluginManager { ...@@ -874,21 +897,8 @@ public class PluginManager {
// needs to be unloaded and then reloaded. // needs to be unloaded and then reloaded.
else if (jarFile.lastModified() > dir.lastModified()) { else if (jarFile.lastModified() > dir.lastModified()) {
unloadPlugin(pluginName); unloadPlugin(pluginName);
// Give the plugin 2 seconds to unload.
Thread.sleep(2000);
// Ask the system to clean up references.
System.gc();
int count = 0;
while (!deleteDir(dir) && count < 5) {
Log.warn("Error unloading plugin " + pluginName + ". " +
"Will attempt again momentarily.");
Thread.sleep(8000);
count++;
// Ask the system to clean up references.
System.gc();
}
// If the delete operation was a success, unzip the plugin. // If the delete operation was a success, unzip the plugin.
if (count != 5) { if (!dir.exists()) {
unzipPlugin(pluginName, jarFile, dir); unzipPlugin(pluginName, jarFile, dir);
} }
} }
...@@ -940,15 +950,6 @@ public class PluginManager { ...@@ -940,15 +950,6 @@ public class PluginManager {
} }
for (String pluginName : toDelete) { for (String pluginName : toDelete) {
unloadPlugin(pluginName); unloadPlugin(pluginName);
System.gc();
int count = 0;
File dir = new File(pluginDirectory, pluginName);
while (!deleteDir(dir) && count < 5) {
Log.error("Error unloading plugin " + pluginName + ". " +
"Will attempt again momentarily.");
Thread.sleep(10000);
count++;
}
} }
// Load all plugins that need to be loaded. // Load all plugins that need to be loaded.
...@@ -1076,47 +1077,48 @@ public class PluginManager { ...@@ -1076,47 +1077,48 @@ public class PluginManager {
} }
} }
/** }
* Deletes a directory.
* /**
* @param dir the directory to delete. * Deletes a directory.
* @return true if the directory was deleted. *
*/ * @param dir the directory to delete.
private boolean deleteDir(File dir) { * @return true if the directory was deleted.
if (dir.isDirectory()) { */
String[] childDirs = dir.list(); private boolean deleteDir(File dir) {
// Always try to delete JAR files first since that's what will if (dir.isDirectory()) {
// be under contention. We do this by always sorting the lib directory String[] childDirs = dir.list();
// first. // Always try to delete JAR files first since that's what will
List<String> children = new ArrayList<String>(Arrays.asList(childDirs)); // be under contention. We do this by always sorting the lib directory
Collections.sort(children, new Comparator<String>() { // first.
public int compare(String o1, String o2) { List<String> children = new ArrayList<String>(Arrays.asList(childDirs));
if (o1.equals("lib")) { Collections.sort(children, new Comparator<String>() {
return -1; public int compare(String o1, String o2) {
} if (o1.equals("lib")) {
if (o2.equals("lib")) { return -1;
return 1;
}
else {
return o1.compareTo(o2);
}
} }
}); if (o2.equals("lib")) {
for (String file : children) { return 1;
boolean success = deleteDir(new File(dir, file)); }
if (!success) { else {
Log.debug("Plugin removal: could not delete: " + new File(dir, file)); return o1.compareTo(o2);
return false;
} }
} }
});
for (String file : children) {
boolean success = deleteDir(new File(dir, file));
if (!success) {
Log.debug("Plugin removal: could not delete: " + new File(dir, file));
return false;
}
} }
boolean deleted = dir.delete();
if (deleted) {
// Remove the JAR/WAR file that created the plugin folder
pluginFiles.remove(dir.getName());
}
return deleted;
} }
boolean deleted = dir.delete();
if (deleted) {
// Remove the JAR/WAR file that created the plugin folder
pluginFiles.remove(dir.getName());
}
return deleted;
} }
public void addPluginListener(PluginListener listener) { public void addPluginListener(PluginListener listener) {
......
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