diff --git a/src/java/com/threerings/crowd/server/LocationProvider.java b/src/java/com/threerings/crowd/server/LocationProvider.java index b3513c9cb..2a4bfdb82 100644 --- a/src/java/com/threerings/crowd/server/LocationProvider.java +++ b/src/java/com/threerings/crowd/server/LocationProvider.java @@ -1,5 +1,5 @@ // -// $Id: LocationProvider.java,v 1.23 2004/08/27 02:12:34 mdb Exp $ +// $Id$ // // Narya library - tools for developing networked games // Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved @@ -28,14 +28,15 @@ import com.threerings.presents.data.ClientObject; import com.threerings.presents.server.InvocationException; import com.threerings.presents.server.InvocationManager; import com.threerings.presents.server.InvocationProvider; +import com.threerings.presents.server.PresentsClient; import com.threerings.crowd.Log; import com.threerings.crowd.client.LocationService; - import com.threerings.crowd.data.BodyObject; import com.threerings.crowd.data.LocationCodes; import com.threerings.crowd.data.PlaceConfig; import com.threerings.crowd.data.PlaceObject; +import com.threerings.crowd.server.CrowdServer; /** * This class provides the server end of the location services. @@ -115,6 +116,16 @@ public class LocationProvider throw new InvocationException(MOVE_IN_PROGRESS); } + // configure the client accordingly if they're moving to a place + // that uses a custom class loader + PresentsClient client = CrowdServer.clmgr.getClient(source.username); + if (client != null) { + client.setClassLoader(_plreg.getClassLoader(pmgr.getConfig())); + } else { + Log.warning("No client for moveTo class loader fiddling? " + + "[who=" + source.username + "]."); + } + try { PlaceObject place = pmgr.getPlaceObject(); diff --git a/src/java/com/threerings/crowd/server/PlaceRegistry.java b/src/java/com/threerings/crowd/server/PlaceRegistry.java index a57b62cc3..38e764f9c 100644 --- a/src/java/com/threerings/crowd/server/PlaceRegistry.java +++ b/src/java/com/threerings/crowd/server/PlaceRegistry.java @@ -81,6 +81,22 @@ public class PlaceRegistry _invmgr = invmgr; } + /** + * By overriding this method, it is possible to customize the place + * registry to cause it to load the classes associated with a + * particular place via a custom class loader. That loader may enforce + * restricted privileges or obtain the classes from some special + * source. + * + * @return the class loader to use when instantiating the {@link + * PlaceManager} associated with the supplied {@link + * PlaceConfig}. This method must not return null. + */ + public ClassLoader getClassLoader (PlaceConfig config) + { + return getClass().getClassLoader(); + } + /** * Creates and registers a new place manager along with the place * object to be managed. The registry takes care of tracking the @@ -264,22 +280,6 @@ public class PlaceRegistry } } - /** - * By overriding this method, it is possible to customize the place - * registry to cause it to load the classes associated with a - * particular place via a custom class loader. That loader may enforce - * restricted privileges or obtain the classes from some special - * source. - * - * @return the class loader to use when instantiating the {@link - * PlaceManager} associated with the supplied {@link - * PlaceConfig}. This method must not return null. - */ - protected ClassLoader getClassLoader (PlaceConfig config) - { - return getClass().getClassLoader(); - } - /** The invocation manager with which we operate. */ protected InvocationManager _invmgr; diff --git a/src/java/com/threerings/presents/server/PresentsClient.java b/src/java/com/threerings/presents/server/PresentsClient.java index 9c9067911..19ca67e40 100644 --- a/src/java/com/threerings/presents/server/PresentsClient.java +++ b/src/java/com/threerings/presents/server/PresentsClient.java @@ -1,5 +1,5 @@ // -// $Id: PresentsClient.java,v 1.69 2004/10/27 01:27:44 mdb Exp $ +// $Id$ // // Narya library - tools for developing networked games // Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved @@ -147,6 +147,19 @@ public class PresentsClient return (conn == null) ? null : conn.getInetAddress(); } + /** + * Configures this client with a custom class loader that will be used + * when unserializing classes from the network. + */ + public void setClassLoader (ClassLoader loader) + { + _loader = loader; + Connection conn = getConnection(); + if (conn != null) { + conn.setClassLoader(loader); + } + } + /** * Danger: this method is not for general consumption. This * changes the username of the client, but should only be done very @@ -660,6 +673,11 @@ public class PresentsClient // a connection rather than clearing one out) if (_conn != null) { _conn.setMessageHandler(this); + + // configure any active custom class loader + if (_loader != null) { + _conn.setClassLoader(_loader); + } } // make a note that our network status changed @@ -897,8 +915,7 @@ public class PresentsClient protected Connection _conn; protected ClientObject _clobj; protected HashIntMap _subscrips = new HashIntMap(); - - protected static HashMap _disps = new HashMap(); + protected ClassLoader _loader; /** The time at which this client started their session. */ protected long _sessionStamp; @@ -916,6 +933,9 @@ public class PresentsClient protected int _messagesOut; protected int _messagesDropped; + /** A mapping of message dispatchers. */ + protected static HashMap _disps = new HashMap(); + /** The amount of time after disconnection a user is allowed before * their session is forcibly ended. */ protected static final long FLUSH_TIME = 7 * 60 * 1000L; diff --git a/src/java/com/threerings/presents/server/net/Connection.java b/src/java/com/threerings/presents/server/net/Connection.java index f971226f2..8740e6aa4 100644 --- a/src/java/com/threerings/presents/server/net/Connection.java +++ b/src/java/com/threerings/presents/server/net/Connection.java @@ -1,5 +1,5 @@ // -// $Id: Connection.java,v 1.20 2004/08/27 02:20:24 mdb Exp $ +// $Id$ // // Narya library - tools for developing networked games // Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved @@ -80,6 +80,17 @@ public abstract class Connection implements NetEventHandler _handler = handler; } + /** + * Configures this connection with a custom class loader. + */ + public void setClassLoader (ClassLoader loader) + { + _loader = loader; + if (_oin != null) { + _oin.setClassLoader(loader); + } + } + /** * Returns the selection key associated with our socket channel. */ @@ -175,6 +186,9 @@ public abstract class Connection implements NetEventHandler _fin = other._fin; _oin = other._oin; _oout = other._oout; + if (_loader != null) { + _oin.setClassLoader(_loader); + } } /** @@ -242,6 +256,9 @@ public abstract class Connection implements NetEventHandler if (_fin == null) { _fin = new FramedInputStream(); _oin = new ObjectInputStream(_fin); + if (_loader != null) { + _oin.setClassLoader(_loader); + } } // there may be more than one frame in the buffer, so we keep @@ -318,10 +335,10 @@ public abstract class Connection implements NetEventHandler protected FramedInputStream _fin; protected ObjectInputStream _oin; - protected ObjectOutputStream _oout; protected MessageHandler _handler; + protected ClassLoader _loader; /** The number of milliseconds beyond the ping interval that we allow * a client's network connection to be idle before we forcibly diff --git a/src/java/com/threerings/resource/ResourceManager.java b/src/java/com/threerings/resource/ResourceManager.java index 243900022..fcce58d39 100644 --- a/src/java/com/threerings/resource/ResourceManager.java +++ b/src/java/com/threerings/resource/ResourceManager.java @@ -1,5 +1,5 @@ // -// $Id: ResourceManager.java,v 1.46 2004/08/27 02:20:34 mdb Exp $ +// $Id$ // // Narya library - tools for developing networked games // Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved @@ -160,14 +160,21 @@ public class ResourceManager */ public ResourceManager (String resourceRoot) { - // keep track of our root path + this(resourceRoot, ResourceManager.class.getClassLoader()); + } + + /** + * Creates a resource manager with the specified class loader via + * which to load classes. See {@link ResourceManager(String)} for + * further documentation. + */ + public ResourceManager (String resourceRoot, ClassLoader loader) + { _rootPath = resourceRoot; + _loader = loader; - // use the classloader that loaded us - _loader = getClass().getClassLoader(); - - // set up a URL handler so that things can be loaded via - // urls with the 'resource' protocol + // set up a URL handler so that things can be loaded via urls with + // the 'resource' protocol Handler.registerHandler(this); } @@ -372,6 +379,7 @@ public class ResourceManager // if we didn't find anything, try the classloader String rpath = PathUtil.appendPath(_rootPath, path); + Log.info("looing for resource in " + _loader); in = _loader.getResourceAsStream(rpath); if (in != null) { return in; @@ -406,6 +414,7 @@ public class ResourceManager // if we didn't find anything, try the classloader String rpath = PathUtil.appendPath(_rootPath, path); + Log.info("looing for resource in " + _loader); InputStream in = _loader.getResourceAsStream(rpath); if (in != null) { return new MemoryCacheImageInputStream(new BufferedInputStream(in));