Commit 9ee01611 authored by Gaston Dombiak's avatar Gaston Dombiak Committed by gato

Do not start listener on ports until server tried to load plugins.

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/trunk@8296 b35dd754-fafc-0310-a699-88a17e54d16e
parent 83a2431c
...@@ -49,6 +49,10 @@ public class PluginManager { ...@@ -49,6 +49,10 @@ public class PluginManager {
private Map<String, Plugin> plugins; private Map<String, Plugin> plugins;
private Map<Plugin, PluginClassLoader> classloaders; private Map<Plugin, PluginClassLoader> classloaders;
private Map<Plugin, File> pluginDirs; private Map<Plugin, File> pluginDirs;
/**
* Keep track of plugin names and their unzipped files. This list is updated when plugin
* is exploded and not when is loaded.
*/
private Map<String, File> pluginFiles; private Map<String, File> pluginFiles;
private ScheduledExecutorService executor = null; private ScheduledExecutorService executor = null;
private Map<Plugin, PluginDevEnvironment> pluginDevelopment; private Map<Plugin, PluginDevEnvironment> pluginDevelopment;
...@@ -57,6 +61,7 @@ public class PluginManager { ...@@ -57,6 +61,7 @@ public class PluginManager {
private Set<String> devPlugins; private Set<String> devPlugins;
private PluginMonitor pluginMonitor; private PluginMonitor pluginMonitor;
private Set<PluginListener> pluginListeners = new CopyOnWriteArraySet<PluginListener>(); private Set<PluginListener> pluginListeners = new CopyOnWriteArraySet<PluginListener>();
private Set<PluginManagerListener> pluginManagerListeners = new CopyOnWriteArraySet<PluginManagerListener>();
/** /**
* Constructs a new plugin manager. * Constructs a new plugin manager.
...@@ -202,6 +207,20 @@ public class PluginManager { ...@@ -202,6 +207,20 @@ public class PluginManager {
return pluginFiles.get(name); return pluginFiles.get(name);
} }
/**
* Returns true if at least one attempt to load plugins has been done. A true value does not mean
* that available plugins have been loaded nor that plugins to be added in the future are already
* loaded. :)<p>
*
* TODO Current version does not consider child plugins that may be loaded in a second attempt. It either
* TODO consider plugins that were found but failed to be loaded due to some error.
*
* @return true if at least one attempt to load plugins has been done.
*/
public boolean isExecuted() {
return pluginMonitor.executed;
}
/** /**
* Loads a plug-in module into the container. Loading consists of the * Loads a plug-in module into the container. Loading consists of the
* following steps:<ul> * following steps:<ul>
...@@ -483,6 +502,12 @@ public class PluginManager { ...@@ -483,6 +502,12 @@ public class PluginManager {
} }
} }
private void firePluginsMonitored() {
for(PluginManagerListener listener : pluginManagerListeners) {
listener.pluginsMonitored();
}
}
/** /**
* Unloads a plugin. The {@link Plugin#destroyPlugin()} method will be called and then * Unloads a plugin. The {@link Plugin#destroyPlugin()} method will be called and then
* any resources will be released. The name should be the name of the plugin directory * any resources will be released. The name should be the name of the plugin directory
...@@ -794,6 +819,12 @@ public class PluginManager { ...@@ -794,6 +819,12 @@ public class PluginManager {
*/ */
private boolean running = false; private boolean running = false;
/**
* True if the monitor has been executed at least once. After the first iteration in {@link #run}
* this variable will always be true.
* */
private boolean executed = false;
public void run() { public void run() {
// If the task is already running, return. // If the task is already running, return.
synchronized (this) { synchronized (this) {
...@@ -833,6 +864,8 @@ public class PluginManager { ...@@ -833,6 +864,8 @@ public class PluginManager {
jarFile.getName().length() - 4).toLowerCase(); jarFile.getName().length() - 4).toLowerCase();
// See if the JAR has already been exploded. // See if the JAR has already been exploded.
File dir = new File(pluginDirectory, pluginName); File dir = new File(pluginDirectory, pluginName);
// Store the JAR/WAR file that created the plugin folder
pluginFiles.put(pluginName, jarFile);
// If the JAR hasn't been exploded, do so. // If the JAR hasn't been exploded, do so.
if (!dir.exists()) { if (!dir.exists()) {
unzipPlugin(pluginName, jarFile, dir); unzipPlugin(pluginName, jarFile, dir);
...@@ -925,6 +958,14 @@ public class PluginManager { ...@@ -925,6 +958,14 @@ public class PluginManager {
loadPlugin(dirFile); loadPlugin(dirFile);
} }
} }
// Set that at least one iteration was done. That means that "all available" plugins
// have been loaded by now.
if (!XMPPServer.getInstance().isSetupMode()) {
executed = true;
}
// Trigger event that plugins have been monitored
firePluginsMonitored();
} }
catch (Throwable e) { catch (Throwable e) {
Log.error(e); Log.error(e);
...@@ -980,9 +1021,6 @@ public class PluginManager { ...@@ -980,9 +1021,6 @@ public class PluginManager {
// The lib directory of the plugin may contain Pack200 versions of the JAR // The lib directory of the plugin may contain Pack200 versions of the JAR
// file. If so, unpack them. // file. If so, unpack them.
unpackArchives(new File(dir, "lib")); unpackArchives(new File(dir, "lib"));
// Store the JAR/WAR file that created the plugin folder
pluginFiles.put(pluginName, file);
} }
catch (Exception e) { catch (Exception e) {
Log.error(e); Log.error(e);
...@@ -1088,4 +1126,15 @@ public class PluginManager { ...@@ -1088,4 +1126,15 @@ public class PluginManager {
public void removePluginListener(PluginListener listener) { public void removePluginListener(PluginListener listener) {
pluginListeners.remove(listener); pluginListeners.remove(listener);
} }
public void addPluginManagerListener(PluginManagerListener listener) {
pluginManagerListeners.add(listener);
if (isExecuted()) {
firePluginsMonitored();
}
}
public void removePluginManagerListener(PluginManagerListener listener) {
pluginManagerListeners.remove(listener);
}
} }
\ No newline at end of file
...@@ -21,14 +21,16 @@ import org.apache.mina.filter.executor.ExecutorFilter; ...@@ -21,14 +21,16 @@ import org.apache.mina.filter.executor.ExecutorFilter;
import org.apache.mina.transport.socket.nio.SocketAcceptor; import org.apache.mina.transport.socket.nio.SocketAcceptor;
import org.apache.mina.transport.socket.nio.SocketAcceptorConfig; import org.apache.mina.transport.socket.nio.SocketAcceptorConfig;
import org.apache.mina.transport.socket.nio.SocketSessionConfig; import org.apache.mina.transport.socket.nio.SocketSessionConfig;
import org.jivesoftware.util.*;
import org.jivesoftware.openfire.*; import org.jivesoftware.openfire.*;
import org.jivesoftware.openfire.container.BasicModule; import org.jivesoftware.openfire.container.BasicModule;
import org.jivesoftware.openfire.container.PluginManager;
import org.jivesoftware.openfire.container.PluginManagerListener;
import org.jivesoftware.openfire.http.HttpBindManager; import org.jivesoftware.openfire.http.HttpBindManager;
import org.jivesoftware.openfire.net.*; import org.jivesoftware.openfire.net.*;
import org.jivesoftware.openfire.nio.ClientConnectionHandler; import org.jivesoftware.openfire.nio.ClientConnectionHandler;
import org.jivesoftware.openfire.nio.MultiplexerConnectionHandler; import org.jivesoftware.openfire.nio.MultiplexerConnectionHandler;
import org.jivesoftware.openfire.nio.XMPPCodecFactory; import org.jivesoftware.openfire.nio.XMPPCodecFactory;
import org.jivesoftware.util.*;
import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
...@@ -64,8 +66,6 @@ public class ConnectionManagerImpl extends BasicModule implements ConnectionMana ...@@ -64,8 +66,6 @@ public class ConnectionManagerImpl extends BasicModule implements ConnectionMana
private XMPPServer server; private XMPPServer server;
private String localIPAddress = null; private String localIPAddress = null;
// Used to know if the sockets can be started (the connection manager has been started)
private boolean isStarted = false;
// Used to know if the sockets have been started // Used to know if the sockets have been started
private boolean isSocketStarted = false; private boolean isSocketStarted = false;
...@@ -74,13 +74,24 @@ public class ConnectionManagerImpl extends BasicModule implements ConnectionMana ...@@ -74,13 +74,24 @@ public class ConnectionManagerImpl extends BasicModule implements ConnectionMana
ports = new ArrayList<ServerPort>(4); ports = new ArrayList<ServerPort>(4);
} }
private void createSocket() { private synchronized void createSocket() {
if (!isStarted || isSocketStarted || sessionManager == null || deliverer == null || if (isSocketStarted || sessionManager == null || deliverer == null || router == null || serverName == null) {
router == null || return;
serverName == null) }
{ // Check if plugins have been loaded
PluginManager pluginManager = XMPPServer.getInstance().getPluginManager();
if (!pluginManager.isExecuted()) {
pluginManager.addPluginManagerListener(new PluginManagerListener() {
public void pluginsMonitored() {
// Stop listening for plugin events
XMPPServer.getInstance().getPluginManager().removePluginManagerListener(this);
// Start listeners
createSocket();
}
});
return; return;
} }
isSocketStarted = true; isSocketStarted = true;
// Setup port info // Setup port info
...@@ -669,7 +680,7 @@ public class ConnectionManagerImpl extends BasicModule implements ConnectionMana ...@@ -669,7 +680,7 @@ public class ConnectionManagerImpl extends BasicModule implements ConnectionMana
ioThreads + 1, ioThreads + 1, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>() ); ioThreads + 1, ioThreads + 1, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>() );
socketAcceptor = new SocketAcceptor(ioThreads, ioExecutor); socketAcceptor = new SocketAcceptor(ioThreads, ioExecutor);
// Set that it will be possible to bind a socket if there is a connection in the timeout state // Set that it will be possible to bind a socket if there is a connection in the timeout state
SocketAcceptorConfig socketAcceptorConfig = (SocketAcceptorConfig) socketAcceptor.getDefaultConfig(); SocketAcceptorConfig socketAcceptorConfig = socketAcceptor.getDefaultConfig();
socketAcceptorConfig.setReuseAddress(true); socketAcceptorConfig.setReuseAddress(true);
// Set the listen backlog (queue) length. Default is 50. // Set the listen backlog (queue) length. Default is 50.
socketAcceptorConfig.setBacklog(JiveGlobals.getIntProperty("xmpp.socket.backlog", 50)); socketAcceptorConfig.setBacklog(JiveGlobals.getIntProperty("xmpp.socket.backlog", 50));
...@@ -700,7 +711,6 @@ public class ConnectionManagerImpl extends BasicModule implements ConnectionMana ...@@ -700,7 +711,6 @@ public class ConnectionManagerImpl extends BasicModule implements ConnectionMana
public void start() { public void start() {
super.start(); super.start();
isStarted = true;
serverName = server.getServerInfo().getName(); serverName = server.getServerInfo().getName();
createSocket(); createSocket();
SocketSendingTracker.getInstance().start(); SocketSendingTracker.getInstance().start();
......
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