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 {
private Map<String, Plugin> plugins;
private Map<Plugin, PluginClassLoader> classloaders;
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 ScheduledExecutorService executor = null;
private Map<Plugin, PluginDevEnvironment> pluginDevelopment;
......@@ -57,6 +61,7 @@ public class PluginManager {
private Set<String> devPlugins;
private PluginMonitor pluginMonitor;
private Set<PluginListener> pluginListeners = new CopyOnWriteArraySet<PluginListener>();
private Set<PluginManagerListener> pluginManagerListeners = new CopyOnWriteArraySet<PluginManagerListener>();
/**
* Constructs a new plugin manager.
......@@ -202,6 +207,20 @@ public class PluginManager {
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
* following steps:<ul>
......@@ -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
* any resources will be released. The name should be the name of the plugin directory
......@@ -794,6 +819,12 @@ public class PluginManager {
*/
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() {
// If the task is already running, return.
synchronized (this) {
......@@ -833,6 +864,8 @@ public class PluginManager {
jarFile.getName().length() - 4).toLowerCase();
// See if the JAR has already been exploded.
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 (!dir.exists()) {
unzipPlugin(pluginName, jarFile, dir);
......@@ -925,6 +958,14 @@ public class PluginManager {
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) {
Log.error(e);
......@@ -980,9 +1021,6 @@ public class PluginManager {
// The lib directory of the plugin may contain Pack200 versions of the JAR
// file. If so, unpack them.
unpackArchives(new File(dir, "lib"));
// Store the JAR/WAR file that created the plugin folder
pluginFiles.put(pluginName, file);
}
catch (Exception e) {
Log.error(e);
......@@ -1088,4 +1126,15 @@ public class PluginManager {
public void removePluginListener(PluginListener 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;
import org.apache.mina.transport.socket.nio.SocketAcceptor;
import org.apache.mina.transport.socket.nio.SocketAcceptorConfig;
import org.apache.mina.transport.socket.nio.SocketSessionConfig;
import org.jivesoftware.util.*;
import org.jivesoftware.openfire.*;
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.net.*;
import org.jivesoftware.openfire.nio.ClientConnectionHandler;
import org.jivesoftware.openfire.nio.MultiplexerConnectionHandler;
import org.jivesoftware.openfire.nio.XMPPCodecFactory;
import org.jivesoftware.util.*;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
......@@ -64,8 +66,6 @@ public class ConnectionManagerImpl extends BasicModule implements ConnectionMana
private XMPPServer server;
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
private boolean isSocketStarted = false;
......@@ -74,13 +74,24 @@ public class ConnectionManagerImpl extends BasicModule implements ConnectionMana
ports = new ArrayList<ServerPort>(4);
}
private void createSocket() {
if (!isStarted || isSocketStarted || sessionManager == null || deliverer == null ||
router == null ||
serverName == null)
{
private synchronized void createSocket() {
if (isSocketStarted || sessionManager == null || deliverer == null || router == null || serverName == null) {
return;
}
// 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;
}
isSocketStarted = true;
// Setup port info
......@@ -669,7 +680,7 @@ public class ConnectionManagerImpl extends BasicModule implements ConnectionMana
ioThreads + 1, ioThreads + 1, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>() );
socketAcceptor = new SocketAcceptor(ioThreads, ioExecutor);
// 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);
// Set the listen backlog (queue) length. Default is 50.
socketAcceptorConfig.setBacklog(JiveGlobals.getIntProperty("xmpp.socket.backlog", 50));
......@@ -700,7 +711,6 @@ public class ConnectionManagerImpl extends BasicModule implements ConnectionMana
public void start() {
super.start();
isStarted = true;
serverName = server.getServerInfo().getName();
createSocket();
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