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

More work when unloading plugins.

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/trunk@9521 b35dd754-fafc-0310-a699-88a17e54d16e
parent 83beca64
/**
* $Revision: $
* $Date: $
*
* Copyright (C) 2004-2007 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.openfire.container;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.util.cache.ClusterTask;
import org.jivesoftware.util.cache.ExternalizableUtil;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
/**
* Task that will be run in each cluster node to learn if the specified plugin
* is installed or not.
*
* @author Gaston Dombiak
*/
public class IsPluginInstalledTask implements ClusterTask {
private String pluginName;
private boolean installed;
/**
* Do not use this constructor. It exists for deserialization purposes.
*/
public IsPluginInstalledTask() {
}
public IsPluginInstalledTask(String pluginName) {
this.pluginName = pluginName;
}
public Object getResult() {
return installed;
}
public void run() {
installed = XMPPServer.getInstance().getPluginManager().getPlugin(pluginName) != null;
}
public void writeExternal(ObjectOutput out) throws IOException {
ExternalizableUtil.getInstance().writeSafeUTF(out, pluginName);
}
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
pluginName = ExternalizableUtil.getInstance().readSafeUTF(in);
}
}
......@@ -15,10 +15,7 @@ import org.jivesoftware.util.JiveConstants;
import org.jivesoftware.util.Log;
import org.jivesoftware.util.cache.CacheFactory;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
/**
* A simple registry of cache configuration data for plugins.
......@@ -70,8 +67,16 @@ public class PluginCacheRegistry {
if (caches != null) {
for (CacheInfo info : caches) {
extraCacheMappings.remove(info.getCacheName());
// Check if other cluster nodes have this plugin installed
Collection<Object> answers =
CacheFactory.doSynchronousClusterTask(new IsPluginInstalledTask(pluginName), false);
for (Object installed : answers) {
if ((Boolean) installed) {
return;
}
}
// Destroy cache if we are the last node hosting this plugin
try {
// TODO Destroy cache if we are the last node hosting this plugin
CacheFactory.destroyCache(info.getCacheName());
}
catch (Exception e) {
......
......@@ -587,6 +587,14 @@ public class PluginManager {
}
}
// Remove references to the plugin so it can be unloaded from memory
// If plugin still fails to be removed then we will add references back
// Anyway, for a few seconds admins may not see the plugin in the admin console
// and in a subsequent refresh it will appear if failed to be removed
plugins.remove(pluginName);
File pluginFile = pluginDirs.remove(plugin);
PluginClassLoader pluginLoader = classloaders.remove(plugin);
// Try to remove the folder where the plugin was exploded. If this works then
// the plugin was successfully removed. Otherwise, some objects created by the
// plugin are still in memory.
......@@ -612,10 +620,6 @@ public class PluginManager {
// Unregister plugin caches
PluginCacheRegistry.getInstance().unregisterCaches(pluginName);
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)) {
......@@ -624,6 +628,12 @@ public class PluginManager {
childPluginMap.remove(plugin);
firePluginDestroyedEvent(pluginName, plugin);
}
else {
// Restore references since we failed to remove the plugin
plugins.put(pluginName, plugin);
pluginDirs.put(plugin, pluginFile);
classloaders.put(plugin, pluginLoader);
}
}
private void firePluginDestroyedEvent(String name, Plugin plugin) {
......
......@@ -77,6 +77,7 @@ public class SipManager implements Plugin, PropertyEventListener {
public void destroyPlugin() {
PropertyEventDispatcher.removeListener(this);
// Unregister component.
if (componentManager != null) {
try {
componentManager.removeComponent(serviceName);
} catch (Exception e) {
......@@ -87,6 +88,7 @@ public class SipManager implements Plugin, PropertyEventListener {
} catch (Exception e) {
componentManager.getLog().error(e);
}
}
sipComponent = null;
logComponent = null;
componentManager = null;
......
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