You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@river.apache.org by pe...@apache.org on 2014/05/09 09:03:19 UTC

svn commit: r1593493 [10/24] - in /river/jtsk/skunk/qa_refactor/trunk: qa/ qa/src/com/sun/jini/test/impl/end2end/jssewrapper/ qa/src/com/sun/jini/test/impl/joinmanager/ qa/src/com/sun/jini/test/impl/mahalo/ qa/src/com/sun/jini/test/impl/outrigger/match...

Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/jeri/internal/mux/MuxServer.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/jeri/internal/mux/MuxServer.java?rev=1593493&r1=1593492&r2=1593493&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/jeri/internal/mux/MuxServer.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/jeri/internal/mux/MuxServer.java Fri May  9 07:03:18 2014
@@ -1,263 +1,266 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * 
- *      http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.sun.jini.jeri.internal.mux;
-
-import com.sun.jini.action.GetIntegerAction;
-import com.sun.jini.thread.Executor;
-import com.sun.jini.thread.GetThreadPoolAction;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.channels.SocketChannel;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.Collection;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import net.jini.core.constraint.InvocationConstraints;
-import net.jini.io.UnsupportedConstraintException;
-import net.jini.jeri.InboundRequest;
-import net.jini.jeri.RequestDispatcher;
-import net.jini.security.Security;
-import net.jini.security.SecurityContext;
-
-/**
- * A MuxServer controls the server side of a multiplexed connection.
- *
- * @author Sun Microsystems, Inc.
- **/
-public class MuxServer extends Mux {
-
-    /** initial inbound ration as server, default is 32768 */
-    private static final int serverInitialInboundRation =
-	((Integer) AccessController.doPrivileged(new GetIntegerAction(
-	    "com.sun.jini.jeri.connection.mux.server.initialInboundRation",
-	    32768))).intValue();
-
-    /**
-     * pool of threads for executing tasks with user code: used for
-     * dispatching incoming requests to request dispatchers
-     **/
-    private static final Executor userThreadPool =
-	(Executor) AccessController.doPrivileged(
-	    new GetThreadPoolAction(true));
-
-    /** mux logger */
-    private static final Logger logger =
-	Logger.getLogger("net.jini.jeri.connection.mux");
-
-    /** the request dispatcher to dispatch incoming requests to */
-    private final RequestDispatcher requestDispatcher;
-
-    /** the security context to dispatch incoming requests in */
-    private final SecurityContext securityContext;
-
-    /**
-     * Initiates the server side of a multiplexed connection over the
-     * given input/output stream pair.
-     *
-     * @param out the output stream of the underlying connection
-     *
-     * @param in the input stream of the underlying connection
-     *
-     * @param requestDispatcher the request dispatcher to dispatch
-     * incoming requests received on this multiplexed connection to
-     **/
-    public MuxServer(OutputStream out, InputStream in,
-		     RequestDispatcher requestDispatcher)
-	throws IOException
-    {
-	super(out, in, Mux.SERVER, serverInitialInboundRation, 1024);
-
-	this.requestDispatcher = requestDispatcher;
-	this.securityContext = Security.getContext();
-    }
-
-    public MuxServer(SocketChannel channel,
-		     RequestDispatcher requestDispatcher)
-	throws IOException
-    {
-	super(channel, Mux.SERVER, serverInitialInboundRation, 1024);
-
-	this.requestDispatcher = requestDispatcher;
-	this.securityContext = Security.getContext();
-    }
-
-    /**
-     * Shuts down this multiplexed connection.  Requests in progress
-     * will throw IOException for future I/O operations.
-     *
-     * On the client side, requests that were in progress will appear
-     * to have been aborted with unknown partial execution status.
-     *
-     * @param message reason for shutdown to be included in
-     * IOExceptions thrown from future I/O operations
-     **/
-    public void shutdown(String message) {
-	synchronized (muxLock) {
-	    /*
-	     * Be graceful, if possible: i.e. if there are no busy sessions.
-	     * REMIND: this current implementation is extremely conservative,
-	     * because most previously-used sessions will still appear busy!
-	     *
-	     * We can only send a Shutdown message if we have already sent
-	     * the ServerConnectionHeader.  The header may not have been sent
-	     * if, for example, the ServerEndpointListener was closed right
-	     * as a connection was accepted.  REMIND: should/could we try to
-	     * send a ServerConnectionHeader here, in order to be able to
-	     * send the Shutdown message?
-	     */
-	    if (serverConnectionReady && busySessions.isEmpty()) {
-		asyncSendShutdown(null);
-	    }
-	    setDown(message, null);
-	}
-    }
-
-    /**
-     * Shuts down this multiplexed connection only if there are no
-     * requests in progress (i.e. requests that have been dispatched
-     * to the request dispatcher but that have not been aborted or had
-     * their response fully written to the client).
-     *
-     * @return true if the connection was shut down (because there
-     * were no requests in progress), and false otherwise
-     **/
-    public boolean shutdownGracefully() {
-	synchronized (muxLock) {
-	    if (busySessions.isEmpty()) {
-		asyncSendShutdown(null);
-		setDown("mux connection shut down gracefully", null);
-		return true;
-	    } else {
-		return false;
-	    }
-	}
-    }
-
-    /**
-     * Verifies that the calling context has all of the security
-     * permissions necessary to receive a request on this connection.
-     *
-     * This method should be overridden by subclasses to implement the
-     * desired behavior of the checkPermissions method for
-     * InboundRequest instances generated for this connection.
-     **/
-    protected void checkPermissions() {
-    }
-
-    /**
-     * Checks that the specified requirements are either fully or
-     * partially satisfied by the constraints actually in force for
-     * this connection, and returns any constraints that must be fully
-     * or partially implemented by higher layers in order to fully
-     * satisfy all of the specified requirements.
-     *
-     * This method should be overridden by subclasses to implement the
-     * desired behavior of the checkConstraints method for
-     * InboundRequest instances generated for this connection.
-     **/
-    protected InvocationConstraints
-	checkConstraints(InvocationConstraints constraints)
-	throws UnsupportedConstraintException
-    {
-	if (constraints.requirements().isEmpty()) {
-	    return InvocationConstraints.EMPTY;
-	}
-	throw new UnsupportedConstraintException(
-	    "cannot satisfy constraints: " + constraints);
-    }
-
-    /**
-     * Populates the context collection with information representing
-     * this connection (such as the client host).
-     *
-     * This method should be overridden by subclasses to implement the
-     * desired behavior of the populateContext method for
-     * InboundRequest instances generated for this connection.
-     **/
-    protected void populateContext(Collection context) {
-    }
-
-    /**
-     * Handles message to open a new session over this connection.
-     *
-     * This method must NOT be invoked while synchronized on muxLock.
-     **/
-    void handleOpen(int sessionID) throws ProtocolException {
-	assert !Thread.holdsLock(muxLock);
-
-	Session session;
-	synchronized (muxLock) {
-	    if (!busySessions.get(sessionID)) {
-		dispatchNewRequest(sessionID);
-		return;
-	    } else {
-		session = (Session) sessions.get(Integer.valueOf(sessionID));
-		assert session != null;
-	    }
-	}
-
-	session.handleOpen();
-
-	synchronized (muxLock) {
-	    dispatchNewRequest(sessionID);
-	}
-    }
-
-    private void dispatchNewRequest(int sessionID) throws ProtocolException {
-	assert Thread.holdsLock(muxLock);
-	if (muxDown) {
-	    throw new ProtocolException(
-		"connection down, cannot add new session");
-	}
-	/*
-	 * REMIND: Here we might want to decide to reject the session,
-	 * if current conditions warrant.
-	 */
-	final Session session = new Session(this, sessionID, Session.SERVER);
-	addSession(sessionID, session);
-	try {
-	    userThreadPool.execute(new Runnable() {
-		public void run() {
-		    final InboundRequest request = session.getInboundRequest();
-		    try {
-			AccessController.doPrivileged(securityContext.wrap(
-			    new PrivilegedAction() {
-				public Object run() {
-				    requestDispatcher.dispatch(request);
-				    return null;
-				}
-			    }), securityContext.getAccessControlContext());
-		    } finally {
-			request.abort();
-		    }
-		}
-	    }, "mux request dispatch");
-	} catch (OutOfMemoryError e) {	// assume out of threads
-	    try {
-		logger.log(Level.WARNING,
-			   "could not create thread for request dispatch", e);
-	    } catch (Throwable t) {
-	    }
-	    // reject request but absorb exception to preserve connection
-	    session.abort();
-	}
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.sun.jini.jeri.internal.mux;
+
+import com.sun.jini.action.GetIntegerAction;
+import com.sun.jini.thread.Executor;
+import com.sun.jini.thread.GetThreadPoolAction;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.channels.SocketChannel;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Collection;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import net.jini.core.constraint.InvocationConstraints;
+import net.jini.io.UnsupportedConstraintException;
+import net.jini.jeri.InboundRequest;
+import net.jini.jeri.RequestDispatcher;
+import net.jini.security.Security;
+import net.jini.security.SecurityContext;
+
+/**
+ * A MuxServer controls the server side of a multiplexed connection.
+ *
+ * @author Sun Microsystems, Inc.
+ **/
+public class MuxServer extends Mux {
+
+    /** initial inbound ration as server, default is 32768 */
+    private static final int serverInitialInboundRation =
+	((Integer) AccessController.doPrivileged(new GetIntegerAction(
+	    "com.sun.jini.jeri.connection.mux.server.initialInboundRation",
+	    32768))).intValue();
+
+    /**
+     * pool of threads for executing tasks with user code: used for
+     * dispatching incoming requests to request dispatchers
+     **/
+    private static final Executor userThreadPool =
+	(Executor) AccessController.doPrivileged(
+	    new GetThreadPoolAction(true));
+
+    /** mux logger */
+    private static final Logger logger =
+	Logger.getLogger("net.jini.jeri.connection.mux");
+
+    /** the request dispatcher to dispatch incoming requests to */
+    private final RequestDispatcher requestDispatcher;
+
+    /** the security context to dispatch incoming requests in */
+    private final SecurityContext securityContext;
+
+    /**
+     * Initiates the server side of a multiplexed connection over the
+     * given input/output stream pair.
+     *
+     * @param out the output stream of the underlying connection
+     *
+     * @param in the input stream of the underlying connection
+     *
+     * @param requestDispatcher the request dispatcher to dispatch
+     * incoming requests received on this multiplexed connection to
+     **/
+    public MuxServer(OutputStream out, InputStream in,
+		     RequestDispatcher requestDispatcher)
+	throws IOException
+    {
+	super(out, in, Mux.SERVER, serverInitialInboundRation, 1024);
+
+	this.requestDispatcher = requestDispatcher;
+	this.securityContext = Security.getContext();
+    }
+
+    public MuxServer(SocketChannel channel,
+		     RequestDispatcher requestDispatcher)
+	throws IOException
+    {
+	super(channel, Mux.SERVER, serverInitialInboundRation, 1024);
+
+	this.requestDispatcher = requestDispatcher;
+	this.securityContext = Security.getContext();
+    }
+
+    /**
+     * Shuts down this multiplexed connection.  Requests in progress
+     * will throw IOException for future I/O operations.
+     *
+     * On the client side, requests that were in progress will appear
+     * to have been aborted with unknown partial execution status.
+     *
+     * @param message reason for shutdown to be included in
+     * IOExceptions thrown from future I/O operations
+     **/
+    public void shutdown(String message) {
+	synchronized (muxLock) {
+	    /*
+	     * Be graceful, if possible: i.e. if there are no busy sessions.
+	     * REMIND: this current implementation is extremely conservative,
+	     * because most previously-used sessions will still appear busy!
+	     *
+	     * We can only send a Shutdown message if we have already sent
+	     * the ServerConnectionHeader.  The header may not have been sent
+	     * if, for example, the ServerEndpointListener was closed right
+	     * as a connection was accepted.  REMIND: should/could we try to
+	     * send a ServerConnectionHeader here, in order to be able to
+	     * send the Shutdown message?
+	     */
+	    if (serverConnectionReady && busySessions.isEmpty()) {
+		asyncSendShutdown(null);
+	    }
+	    setDown(message, null);
+	}
+    }
+
+    /**
+     * Shuts down this multiplexed connection only if there are no
+     * requests in progress (i.e. requests that have been dispatched
+     * to the request dispatcher but that have not been aborted or had
+     * their response fully written to the client).
+     *
+     * @return true if the connection was shut down (because there
+     * were no requests in progress), and false otherwise
+     **/
+    public boolean shutdownGracefully() {
+	synchronized (muxLock) {
+	    if (busySessions.isEmpty()) {
+		asyncSendShutdown(null);
+		setDown("mux connection shut down gracefully", null);
+		return true;
+	    } else {
+		return false;
+	    }
+	}
+    }
+
+    /**
+     * Verifies that the calling context has all of the security
+     * permissions necessary to receive a request on this connection.
+     *
+     * This method should be overridden by subclasses to implement the
+     * desired behavior of the checkPermissions method for
+     * InboundRequest instances generated for this connection.
+     **/
+    protected void checkPermissions() {
+    }
+
+    /**
+     * Checks that the specified requirements are either fully or
+     * partially satisfied by the constraints actually in force for
+     * this connection, and returns any constraints that must be fully
+     * or partially implemented by higher layers in order to fully
+     * satisfy all of the specified requirements.
+     *
+     * This method should be overridden by subclasses to implement the
+     * desired behavior of the checkConstraints method for
+     * InboundRequest instances generated for this connection.
+     **/
+    protected InvocationConstraints
+	checkConstraints(InvocationConstraints constraints)
+	throws UnsupportedConstraintException
+    {
+	if (constraints.requirements().isEmpty()) {
+	    return InvocationConstraints.EMPTY;
+	}
+	throw new UnsupportedConstraintException(
+	    "cannot satisfy constraints: " + constraints);
+    }
+
+    /**
+     * Populates the context collection with information representing
+     * this connection (such as the client host).
+     *
+     * This method should be overridden by subclasses to implement the
+     * desired behavior of the populateContext method for
+     * InboundRequest instances generated for this connection.
+     **/
+    protected void populateContext(Collection context) {
+    }
+
+    /**
+     * Handles message to open a new session over this connection.
+     *
+     * This method must NOT be invoked while synchronized on muxLock.
+     **/
+    @Override
+    void handleOpen(int sessionID) throws ProtocolException {
+	assert !Thread.holdsLock(muxLock);
+
+	Session session;
+	synchronized (muxLock) {
+	    if (!busySessions.get(sessionID)) {
+		dispatchNewRequest(sessionID);
+		return;
+	    } else {
+		session = (Session) sessions.get(Integer.valueOf(sessionID));
+		assert session != null;
+	    }
+	}
+
+	session.handleOpen();
+
+	synchronized (muxLock) {
+	    dispatchNewRequest(sessionID);
+	}
+    }
+
+    private void dispatchNewRequest(int sessionID) throws ProtocolException {
+	assert Thread.holdsLock(muxLock);
+	if (muxDown) {
+	    throw new ProtocolException(
+		"connection down, cannot add new session");
+	}
+	/*
+	 * REMIND: Here we might want to decide to reject the session,
+	 * if current conditions warrant.
+	 */
+	final Session session = new Session(this, sessionID, Session.SERVER);
+	addSession(sessionID, session);
+	try {
+	    userThreadPool.execute(new Runnable() {
+                @Override
+		public void run() {
+		    final InboundRequest request = session.getInboundRequest();
+		    try {
+			AccessController.doPrivileged(securityContext.wrap(
+			    new PrivilegedAction() {
+                                @Override
+				public Object run() {
+				    requestDispatcher.dispatch(request);
+				    return null;
+				}
+			    }), securityContext.getAccessControlContext());
+		    } finally {
+			request.abort();
+		    }
+		}
+	    }, "mux request dispatch");
+	} catch (OutOfMemoryError e) {	// assume out of threads
+	    try {
+		logger.log(Level.WARNING,
+			   "could not create thread for request dispatch", e);
+	    } catch (Throwable t) {
+	    }
+	    // reject request but absorb exception to preserve connection
+	    session.abort();
+	}
+    }
+}

Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/jeri/internal/runtime/Util.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/jeri/internal/runtime/Util.java?rev=1593493&r1=1593492&r2=1593493&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/jeri/internal/runtime/Util.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/jeri/internal/runtime/Util.java Fri May  9 07:03:18 2014
@@ -1,811 +1,811 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * 
- *      http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.sun.jini.jeri.internal.runtime;
-
-import com.sun.jini.collection.WeakIdentityMap;
-import java.io.BufferedReader;
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.lang.ref.SoftReference;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.net.URL;
-import java.rmi.MarshalledObject;
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-import java.rmi.activation.ActivationID;
-import java.security.DigestOutputStream;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.Permission;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.WeakHashMap;
-import java.net.InetAddress;
-import java.rmi.server.ServerNotActiveException;
-import javax.security.auth.Subject;
-import net.jini.export.ServerContext;
-import net.jini.io.context.ClientHost;
-import net.jini.io.context.ClientSubject;
-import net.jini.io.context.ContextPermission;
-import net.jini.io.context.IntegrityEnforcement;
-import net.jini.security.proxytrust.TrustEquivalence;
-
-/**
- * Utility methods for implementing custom remote reference types.
- *
- * @author Sun Microsystems, Inc.
- * 
- */
-public class Util {
-    
-    /** cache of tables mapping methods to hashes */
-    private static TableCache methodToHash_TableCache = new TableCache(true);
-    
-    /** cache of valid proxy remote methods */
-    private static Map proxyRemoteMethodCache = new WeakHashMap();
-
-    /** parameter types for activatable constructor or activate method */
-    private static Class[] paramTypes = {
-	ActivationID.class, MarshalledObject.class
-    };
-
-    /** name of the resource containing prohibited proxy interfaces */
-    private static final String prohibitedProxyInterfacesResource =
-	"com/sun/jini/proxy/resources/" +
-	"InvocationHandler.moreProhibitedProxyInterfaces";
-
-    /** names of interfaces that proxies are prohibited from implementing */
-    private static final Collection prohibitedProxyInterfaces =
-	getProhibitedProxyInterfaces();
-
-    /**
-     * Appends the current thread's stack trace to the stack trace of the
-     * given exception.
-     *
-     * This method is used for exceptions that have been unmarshalled as the
-     * exceptional result of a remote method invocation, so that the
-     * client-side stack trace gets recorded in the exception (while
-     * preserving the server-side stack trace in the exception as well).
-     *
-     * Note that the (somewhat odd) names of this method and the method that
-     * this one internally delegates to are significant because these methods
-     * visually highlight the remote call boundary between the server-side
-     * and the client-side portions to readers of the combined stack trace.
-     */
-    public static void exceptionReceivedFromServer(Throwable t) {
-	__________EXCEPTION_RECEIVED_FROM_SERVER__________(t);
-    }
-
-    private static void __________EXCEPTION_RECEIVED_FROM_SERVER__________(
-	Throwable t)
-    {
-	StackTraceElement[] serverTrace = t.getStackTrace();
-	StackTraceElement[] clientTrace = (new Throwable()).getStackTrace();
-	StackTraceElement[] combinedTrace =
-	    new StackTraceElement[serverTrace.length + clientTrace.length];
-	System.arraycopy(serverTrace, 0, combinedTrace, 0,
-			 serverTrace.length);
-	System.arraycopy(clientTrace, 0, combinedTrace, serverTrace.length,
-			 clientTrace.length);
-	t.setStackTrace(combinedTrace);
-    }
-
-    /**
-     * Clear the stack trace of the given exception by replacing it with
-     * an empty StackTraceElement array, and do the same for all of its
-     * chained causative exceptions.
-     *
-     * This method is used when it is desired for the stack trace data of
-     * an exception to be suppressed before the exception gets marshalled
-     * to a remote virtual machine, perhaps for reasons of confidentiality
-     * or performance.
-     */
-    public static void clearStackTraces(Throwable t) {
-	StackTraceElement[] empty = new StackTraceElement[0];
-	while (t != null) {
-	    t.setStackTrace(empty);
-	    t = t.getCause();
-	}
-    }
-
-    /**
-     * Marshals <code>value</code> to an <code>ObjectOutput</code> stream,
-     * <code>out</code>, using RMI's serialization format for arguments or
-     * return values.  For primitive types, the primitive type's class should
-     * be specified (i.e., for the type <code>int</code>, specify
-     * <code>int.class</code>), and the primitive value should be wrapped in
-     * instances of the appropriate wrapper class, such as
-     * <code>java.lang.Integer</code> or <code>java.lang.Boolean</code>.
-     *
-     * @param	type <code>Class</code> object for the value to be marshalled
-     * @param	value value to marshal
-     * @param	out stream to which the value is marshalled
-     * @throws	IOException if an I/O error occurs marshalling
-     *		the value to the output stream
-     */
-    public static void marshalValue(Class type, Object value, ObjectOutput out)
-	throws IOException
-    {
-	if (type.isPrimitive()) {
-	    if (type == int.class) {
-		out.writeInt(((Integer) value).intValue());
-	    } else if (type == boolean.class) {
-		out.writeBoolean(((Boolean) value).booleanValue());
-	    } else if (type == byte.class) {
-		out.writeByte(((Byte) value).byteValue());
-	    } else if (type == char.class) {
-		out.writeChar(((Character) value).charValue());
-	    } else if (type == short.class) {
-		out.writeShort(((Short) value).shortValue());
-	    } else if (type == long.class) {
-		out.writeLong(((Long) value).longValue());
-	    } else if (type == float.class) {
-		out.writeFloat(((Float) value).floatValue());
-	    } else if (type == double.class) {
-		out.writeDouble(((Double) value).doubleValue());
-	    } else {
-		throw new AssertionError(
-		    "Unrecognized primitive type: " + type);
-	    }
-	} else {
-	    out.writeObject(value);
-	}
-    }
-
-    /**
-     * Unmarshals a value of the specified <code>type</code> from the
-     * <code>ObjectInput</code> stream, <code>in</code>, using RMI's
-     * serialization format for arguments or return values and returns the
-     * result.  For primitive types, the primitive type's class should be
-     * specified (i.e., for the primitive type <code>int</code>, specify
-     * <code>int.class</code>).
-     *
-     * @param	type <code>Class</code> object for the value to be unmarshalled
-     * @param	in stream from which the value is unmarshalled
-     * @return	value unmarshalled from the input stream
-     * @throws	IOException if an I/O error occurs marshalling
-     *		the value to the output stream
-     * @throws	ClassNotFoundException if the <code>type</code>'s
-     *		class could not	be found
-     */
-    public static Object unmarshalValue(Class type, ObjectInput in)
-	throws IOException, ClassNotFoundException
-    {
-	if (type.isPrimitive()) {
-	    if (type == int.class) {
-		return Integer.valueOf(in.readInt());
-	    } else if (type == boolean.class) {
-		return Boolean.valueOf(in.readBoolean());
-	    } else if (type == byte.class) {
-		return Byte.valueOf(in.readByte());
-	    } else if (type == char.class) {
-		return Character.valueOf(in.readChar());
-	    } else if (type == short.class) {
-		return Short.valueOf(in.readShort());
-	    } else if (type == long.class) {
-		return Long.valueOf(in.readLong());
-	    } else if (type == float.class) {
-		return new Float(in.readFloat());
-	    } else if (type == double.class) {
-		return new Double(in.readDouble());
-	    } else {
-		throw new AssertionError(
-		    "Unrecognized primitive type: " + type);
-	    }
-	} else {
-	    return in.readObject();
-	}
-    }
-
-    /**
-     * Computes the "method hash" of a remote method, <code>m</code>.  The
-     * method hash is a <code>long</code> containing the first 64 bits of the
-     * SHA digest from the UTF encoded string of the method name followed by
-     * its "method descriptor".  See section 4.3.3 of The Java(TM) Virtual
-     * Machine Specification for the definition of a "method descriptor".
-     *
-     * @param	m remote method
-     * @return	the method hash
-     */
-    private static long computeMethodHash(Method m) {
-	long hash = 0;
-	ByteArrayOutputStream sink = new ByteArrayOutputStream(127);
-	try {
-	    MessageDigest md = MessageDigest.getInstance("SHA");
-	    DataOutputStream out = new DataOutputStream(
-		new DigestOutputStream(sink, md));
-
-	    String s = getMethodNameAndDescriptor(m);
-	    out.writeUTF(s);
-
-	    // use only the first 64 bits of the digest for the hash
-	    out.flush();
-	    byte hasharray[] = md.digest();
-	    for (int i = 0; i < Math.min(8, hasharray.length); i++) {
-		hash += ((long) (hasharray[i] & 0xFF)) << (i * 8);
-	    }
-	} catch (IOException ignore) {
-	    /* can't happen, but be deterministic anyway. */
-	    hash = -1;
-	} catch (NoSuchAlgorithmException complain) {
-	    throw new SecurityException(complain.getMessage());
-	}
-	return hash;
-    }
-
-    /**
-     * Returns the method hash for the method <code>m</code>.  Subsequent
-     * calls to <code>getMethodHash</code> passing the same method argument
-     * should be faster since this method caches internally the result of the
-     * method to method hash mapping.  The method hash is calculated using the
-     * <code>computeMethodHash</code> method.
-     *
-     * @param	m the remote method
-     * @return	the method hash for the method <code>m</code>
-     */
-    public static long getMethodHash(Method m) {
-	Map table = methodToHash_TableCache.getTable(m.getDeclaringClass());
-	Long hash = (Long) table.get(m);
-	return hash.longValue();
-    }
-
-    private static class TableCache extends WeakHashMap {
-	/**
-	 * if true, the tables map methods to method hashes; if false,
-	 * the tables map method hashes to methods
-	 */
-	private boolean mapsMethodToHash;
-
-	public TableCache(boolean mapsMethodToHash) {
-	    super();
-	    this.mapsMethodToHash = mapsMethodToHash;
-	}
-	
-	public Map getTable(Class remoteClass) {
-	    SoftReference[] tableRef;
-
-	    /*
-	     * Method tables for remote classes are cached in a hash table
-	     * using weak references to hold the Class object keys, so that
-	     * the cache does not prevent the class from being unloaded, and
-	     * using soft references to hold the values, so that the computed
-	     * method tables will generally persist while no objects of the
-	     * remote class are exported, but their storage may be reclaimed
-	     * if necessary, and accidental reachability of the remote class
-	     * through its interfaces is avoided.
-	     */
-	    synchronized (this) {
-		/*
-		 * Look up class in cache; add entry if not found.
-		 */
-		tableRef = (SoftReference[]) get(remoteClass);
-		if (tableRef == null) {
-		    tableRef = new SoftReference[] { null };
-		    put(remoteClass, tableRef);
-		}
-	    }
-
-	    /*
-	     * Check cached reference to method table for this class;
-	     * if it is null, go and create the table.
-	     */
-	    synchronized (tableRef) {
-		Map table = null;
-		if (tableRef[0] != null) {
-		    table = (Map) tableRef[0].get();
-		}
-		if (table == null) {
-		    if (mapsMethodToHash) {
-			/*
-			 * REMIND: if we hand out this table directly, via a
-			 * public API, we need to make this map "unmodifiable".
-			 */
-			table = new LazyMethodToHash_Map();
-		    } else {
-			throw new UnsupportedOperationException();
-		    }
-		    tableRef[0] = new SoftReference(table);
-		}
-		return table;
-	    }
-	}
-    }
-
-
-    /**
-     * Verifies that the supplied method has at least one declared exception
-     * type that is RemoteException or one of its superclasses.  If not,
-     * then this method throws IllegalArgumentException.
-     *
-     * @throws IllegalArgumentException if m is an illegal remote method
-     */
-    private static void checkMethod(Method m) {
-	Class[] ex = m.getExceptionTypes();
-	for (int i = 0; i < ex.length; i++) {
-	    if (ex[i].isAssignableFrom(RemoteException.class))
-		return;
-	}
-	throw new IllegalArgumentException(
-	    "illegal remote method encountered: " + m);
-    }
-    
-    private static class LazyMethodToHash_Map extends WeakHashMap {
-
-	public LazyMethodToHash_Map() {
-	    super();
-	}
-
-	public synchronized Object get(Object key) {
-	    Object hash = super.get(key);
-	    if (hash == null) {
-		Method method = (Method) key;
-		hash = Long.valueOf(computeMethodHash(method));
-		put(method, hash);
-	    }
-	    return (Long) hash;
-	}
-    }
-	    
-    /*
-     * The following static methods are related to the creation of the
-     * "method table" for a remote class, which maps method hashes to
-     * the appropriate Method objects for the class's remote methods.
-     */
-
-    /**
-     * Returns a string consisting of the given method's name followed by
-     * its "method descriptor", as appropriate for use in the computation
-     * of the "method hash".
-     *
-     * See section 4.3.3 of The Java(TM) Virtual Machine Specification for
-     * the definition of a "method descriptor".
-     */
-    public static String getMethodNameAndDescriptor(Method m) {
-	StringBuffer desc = new StringBuffer(m.getName());
-	desc.append('(');
-	Class[] paramTypes = m.getParameterTypes();
-	for (int i = 0; i < paramTypes.length; i++) {
-	    desc.append(getTypeDescriptor(paramTypes[i]));
-	}
-	desc.append(')');
-	Class returnType = m.getReturnType();
-	if (returnType == void.class) {	// optimization: handle void here
-	    desc.append('V');
-	} else {
-	    desc.append(getTypeDescriptor(returnType));
-	}
-	return desc.toString();
-    }
-
-    /**
-     * Returns the descriptor of a particular type, as appropriate for either
-     * a parameter type or return type in a method descriptor.
-     */
-    private static String getTypeDescriptor(Class type) {
-	if (type.isPrimitive()) {
-	    if (type == int.class) {
-		return "I";
-	    } else if (type == boolean.class) {
-		return "Z";
-	    } else if (type == byte.class) {
-		return "B";
-	    } else if (type == char.class) {
-		return "C";
-	    } else if (type == short.class) {
-		return "S";
-	    } else if (type == long.class) {
-		return "J";
-	    } else if (type == float.class) {
-		return "F";
-	    } else if (type == double.class) {
-		return "D";
-	    } else if (type == void.class) {
-		return "V";
-	    } else {
-		throw new Error("unrecognized primitive type: " + type);
-	    }
-	} else if (type.isArray()) {
-	    /*
-	     * According to JLS 20.3.2, the getName() method on Class does
-	     * return the virtual machine type descriptor format for array
-	     * classes (only); using that should be quicker than the otherwise
-	     * obvious code:
-	     *
-	     *     return "[" + getTypeDescriptor(type.getComponentType());
-	     */
-	    return type.getName().replace('.', '/');
-	} else {
-	    return "L" + type.getName().replace('.', '/') + ";";
-	}
-    }
-
-    /**
-     * Returns an array containing the remote interfaces implemented
-     * by the given class.
-     *
-     * @throws	IllegalArgumentException if remoteClass implements
-     * 		any illegal remote interfaces
-     * @throws	NullPointerException if remoteClass is null
-     */
-    public static Class[] getRemoteInterfaces(Class remoteClass) {
-	ArrayList list = new ArrayList();
-	getRemoteInterfaces(list, remoteClass);
-	return (Class []) list.toArray(new Class[list.size()]);
-    }
-
-    /**
-     * Fills the given array list with the remote interfaces implemented
-     * by the given class.
-     *
-     * @throws	IllegalArgumentException if the specified class implements
-     * 		any illegal remote interfaces
-     * @throws	NullPointerException if the specified class or list is null
-     */
-    private static void getRemoteInterfaces(ArrayList list, Class cl) {
-	Class superclass = cl.getSuperclass();
-	if (superclass != null) {
-	    getRemoteInterfaces(list, superclass);
-	}
-	
-	Class[] interfaces = cl.getInterfaces();
-	for (int i = 0; i < interfaces.length; i++) {
-	    Class intf = interfaces[i];
-	    /*
-	     * If it is a remote interface (if it extends from
-	     * java.rmi.Remote) and is not already in the list,
-	     * then add the interface to the list.
-	     */
-	    if (Remote.class.isAssignableFrom(intf)) {
-		if (!(list.contains(intf))) {
-		    Method[] methods = intf.getMethods();
-		    for (int j = 0; j < methods.length; j++) {
-			checkMethod(methods[j]);
-		    }
-		    list.add(intf);
-		}
-	    }
-	}
-    }
-
-    /**
-     * Throws IllegalArgumentException if any superinterface of c declares a
-     * method with the same name and parameter types as m that does not
-     * declare RemoteException or a superclass in its throws clause, or if
-     * any superinterface of c has its name in prohibitedProxyInterfaces.
-     */
-    public static void checkProxyRemoteMethod(Class c, Method m) {
-	WeakIdentityMap map;
-	synchronized (proxyRemoteMethodCache) {
-	    SoftReference ref = (SoftReference) proxyRemoteMethodCache.get(c);
-	    map = (ref == null) ? null : (WeakIdentityMap) ref.get();
-	    if (map == null && ref != null) {
-		map = new WeakIdentityMap();
-		proxyRemoteMethodCache.put(c, new SoftReference(map));
-	    }
-	}
-	if (map == null) {
-	    checkProhibitedProxyInterfaces(c);
-	    synchronized (proxyRemoteMethodCache) {
-		SoftReference ref =
-		    (SoftReference) proxyRemoteMethodCache.get(c);
-		map = (ref == null) ? null : (WeakIdentityMap) ref.get();
-		if (map == null) {
-		    map = new WeakIdentityMap();
-		    proxyRemoteMethodCache.put(c, new SoftReference(map));
-		}
-	    }
-	}
-	synchronized (map) {
-	    if (map.get(m) != null) {
-		return;
-	    }
-	}
-	checkExceptions(c, m.getName(), m.getParameterTypes());
-	synchronized (map) {
-	    map.put(m, Boolean.TRUE);
-	}
-    }
-
-    /**
-     * Throws IllegalArgumentException if any superinterface of c declares a
-     * method with the given name and parameter types that does not declare
-     * RemoteException or a superclass in its throws clause.
-     */
-    private static void checkExceptions(Class c, String name, Class[] types) {
-	Class[] ifaces = c.getInterfaces();
-	for (int i = ifaces.length; --i >= 0; ) {
-	    try {
-		checkMethod(ifaces[i].getMethod(name, types));
-		checkExceptions(ifaces[i], name, types);
-	    } catch (NoSuchMethodException e) {
-	    }
-	}
-    }
-
-    /**
-     * Returns collection of prohibited proxy interfaces read from resources.
-     */
-    private static Collection getProhibitedProxyInterfaces() {
-	Collection names = new HashSet();
-	names.add("javax.management.MBeanServerConnection");
-	Enumeration resources;
-	try {
-	    resources = ClassLoader.getSystemResources(
-					  prohibitedProxyInterfacesResource);
-	} catch (IOException e) {
-	    throw new ExceptionInInitializerError(
-			new IOException(
-			     "problem getting resources: " +
-			     prohibitedProxyInterfacesResource).initCause(e));
-	}
-	while (resources.hasMoreElements()) {
-	    URL url = (URL) resources.nextElement();
-	    try {
-		InputStream in = url.openStream();
-		try {
-		    BufferedReader r =
-			new BufferedReader(new InputStreamReader(in, "utf-8"));
-		    while (true) {
-			String s = r.readLine();
-			if (s == null) {
-			    break;
-			}
-			int i = s.indexOf('#');
-			if (i >= 0) {
-			    s = s.substring(0, i);
-			}
-			s = s.trim();
-			int n = s.length();
-			if (n == 0) {
-			    continue;
-			}
-			char prev = '.';
-			for (i = 0; i < n; i++) {
-			    char c = s.charAt(i);
-			    if (prev == '.' ?
-				!Character.isJavaIdentifierStart(c) :
-				!(Character.isJavaIdentifierPart(c) ||
-				  (c == '.' && i < n - 1)))
-			    {
-				throw new ExceptionInInitializerError(
-					      "illegal interface name in " +
-					      url + ": " + s);
-			    }
-			    prev = c;
-			}
-			names.add(s);
-		    }
-		} finally {
-		    try {
-			in.close();
-		    } catch (IOException e) {
-		    }
-		}
-	    } catch (IOException e) {
-		throw new ExceptionInInitializerError(
-		      new IOException("problem reading " + url).initCause(e));
-	    }
-	}
-	return names;
-    }
-
-    /**
-     * Throws IllegalArgumentException if any superinterface of c has its
-     * name in prohibitedProxyInterfaces.
-     */
-    private static void checkProhibitedProxyInterfaces(Class c) {
-	Class[] ifaces = c.getInterfaces();
-	for (int i = ifaces.length; --i >= 0; ) {
-	    String name = ifaces[i].getName();
-	    if (prohibitedProxyInterfaces.contains(name)) {
-		throw new IllegalArgumentException(
-		       "prohibited proxy interface encountered: " + name);
-	    }
-	    checkProhibitedProxyInterfaces(ifaces[i]);
-	}
-    }
-
-    /**
-     * Returns the binary name of the given type without package
-     * qualification.  Nested types are treated no differently from
-     * top-level types, so for a nested type, the returned name will
-     * still be qualified with the simple name of its enclosing
-     * top-level type (and perhaps other enclosing types), the
-     * separator will be '$', etc.
-     **/
-    public static String getUnqualifiedName(Class c) {
-	String binaryName = c.getName();
-	return binaryName.substring(binaryName.lastIndexOf('.') + 1);
-    }
-
-    /**
-     * Returns true either if both arguments are null or if an
-     * invocation of Object.equals on "subject" with "object" as the
-     * argument returns true; returns false otherwise;
-     **/
-    public static boolean equals(Object subject, Object object) {
-	return subject == null ? object == null : subject.equals(object);
-    }
-
-    /**
-     * Returns true either if both arguments are null or if both
-     * arguments refer to objects of the same class and an invocation
-     * of Object.equals on "subject" with "object" as the argument
-     * returns true; returns false otherwise.
-     *
-     * This method is used to compare to possibly-null references for
-     * object equality when neither object's class is trusted, with
-     * the restriction that only objects of the same class can be
-     * considered equal.
-     **/
-    public static boolean sameClassAndEquals(Object subject, Object object) {
-	return subject == null ? object == null :
-	    object != null &&
-	    subject.getClass() == object.getClass() &&
-	    subject.equals(object);
-    }
-
-    /**
-     * Returns true either if both arguments are null of if "subject"
-     * is an instance of TrustEquivalence and an invocation of
-     * TrustEquivalence.checkTrustEquivalence on "subject" with
-     * "object" as the argument returns true; returns false otherwise.
-     **/
-    public static boolean checkTrustEquivalence(Object subject,
-						Object object)
-    {
-	return subject == null ? object == null :
-	    subject instanceof TrustEquivalence &&
-	    ((TrustEquivalence) subject).checkTrustEquivalence(object);
-    }
-
-    /**
-     * Returns true if proxy2 is a generated Proxy (proxy1 is assumed to
-     * be one) and the classes of both proxies implement the same ordered
-     * list of interfaces, and returns false otherwise.
-     */
-    public static boolean sameProxyClass(Object proxy1, Object proxy2) {
-	return (proxy1.getClass() == proxy2.getClass() ||
-		(Proxy.isProxyClass(proxy2.getClass()) &&
-		 equalInterfaces(proxy1, proxy2)));
-    }
-
-    /**
-     * Returns true if the interfaces implemented by obj1's class
-     * are the same (and in the same order) as obj2's class.
-     */
-    public static boolean equalInterfaces(Object obj1, Object obj2) {
-	Class[] intf1 = obj1.getClass().getInterfaces();
-	Class[] intf2 = obj2.getClass().getInterfaces();
-	if (intf1.length != intf2.length) {
-	    return false;
-	} else {
-	    for (int i = 0; i < intf1.length; i++) {
-		if (intf1[i] != intf2[i]) {
-		    return false;
-		}
-	    }
-	    return true;
-	}
-    }
-    
-    public static void populateContext(Collection context, InetAddress addr) {
-	if (context == null) {
-	    throw new NullPointerException("context is null");
-	}
-	if (addr != null) {
-	    context.add(new ClientHostImpl(addr));
-	}
-    }
-    
-    public static void populateContext(Collection context, Subject s) {
-	if (context == null) {
-	    throw new NullPointerException("context is null");
-	}
-	context.add(new ClientSubjectImpl(s));
-    }
-
-    public static void populateContext(Collection context, boolean integrity) {
-	if (context == null) {
-	    throw new NullPointerException("context is null");
-	}
-	context.add(new IntegrityEnforcementImpl(integrity));
-    }
-
-    private static class ClientHostImpl
-    	implements ClientHost
-    {
-	private final InetAddress addr;
-	public ClientHostImpl(InetAddress addr) { this.addr = addr; }
-	public InetAddress getClientHost() { return addr; }
-    }
-
-    private static class ClientSubjectImpl
-    	implements ClientSubject
-    {
-	private final Subject s;
-	private static final Permission getClientSubjectPerm =
-	    new ContextPermission("net.jini.io.context.ClientSubject.getClientSubject");
-
-	public ClientSubjectImpl(Subject s) { this.s = s; }
-	public Subject getClientSubject() {
-	    SecurityManager sm = System.getSecurityManager();
-	    if (sm != null) {
-		sm.checkPermission(getClientSubjectPerm);
-	    }
-	    return s;
-	}
-    }
-
-    private static class IntegrityEnforcementImpl
-    	implements IntegrityEnforcement
-    {
-	private final boolean integrity;
-	public IntegrityEnforcementImpl(boolean integrity) {
-	    this.integrity = integrity;
-	}
-	public boolean integrityEnforced() { return integrity; }
-    }
-
-    public static InetAddress getClientHost() throws ServerNotActiveException {
-	ClientHost ch = (ClientHost)
-	    ServerContext.getServerContextElement(ClientHost.class);
-	return (ch != null) ? ch.getClientHost() : null;
-    }
-
-    public static String getClientHostString()
-	throws ServerNotActiveException
-    {
-	InetAddress addr = getClientHost();
-	return (addr != null) ? addr.toString() : null;
-    }
-
-    public static Subject getClientSubject() throws ServerNotActiveException {
-	ClientSubject cs = (ClientSubject)
-	    ServerContext.getServerContextElement(ClientSubject.class);
-	return (cs != null) ? cs.getClientSubject() : null;
-    }
-
-    /**
-     * Check for permission to access the package of the specified class.
-     *
-     * @throws SecurityException if a security manager exists and invoking
-     * its <code>checkPackageAccess</code> method with the package name of
-     * the specified class throws a <code>SecurityException</code>
-     */
-    public static void checkPackageAccess(Class type) {
-	SecurityManager security = System.getSecurityManager();
-	if (security != null) {
-	    String name = type.getName();
-	    int i = name.lastIndexOf('.');
-	    if (i != -1) {
-		security.checkPackageAccess(name.substring(0, i));
-	    }
-	}
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.sun.jini.jeri.internal.runtime;
+
+import com.sun.jini.collection.WeakIdentityMap;
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.lang.ref.SoftReference;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.net.URL;
+import java.rmi.MarshalledObject;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.rmi.activation.ActivationID;
+import java.security.DigestOutputStream;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.Permission;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.WeakHashMap;
+import java.net.InetAddress;
+import java.rmi.server.ServerNotActiveException;
+import javax.security.auth.Subject;
+import net.jini.export.ServerContext;
+import net.jini.io.context.ClientHost;
+import net.jini.io.context.ClientSubject;
+import net.jini.io.context.ContextPermission;
+import net.jini.io.context.IntegrityEnforcement;
+import net.jini.security.proxytrust.TrustEquivalence;
+
+/**
+ * Utility methods for implementing custom remote reference types.
+ *
+ * @author Sun Microsystems, Inc.
+ * 
+ */
+public class Util {
+    
+    /** cache of tables mapping methods to hashes */
+    private static TableCache methodToHash_TableCache = new TableCache(true);
+    
+    /** cache of valid proxy remote methods */
+    private static Map proxyRemoteMethodCache = new WeakHashMap();
+
+    /** parameter types for activatable constructor or activate method */
+    private static Class[] paramTypes = {
+	ActivationID.class, MarshalledObject.class
+    };
+
+    /** name of the resource containing prohibited proxy interfaces */
+    private static final String prohibitedProxyInterfacesResource =
+	"com/sun/jini/proxy/resources/" +
+	"InvocationHandler.moreProhibitedProxyInterfaces";
+
+    /** names of interfaces that proxies are prohibited from implementing */
+    private static final Collection prohibitedProxyInterfaces =
+	getProhibitedProxyInterfaces();
+
+    /**
+     * Appends the current thread's stack trace to the stack trace of the
+     * given exception.
+     *
+     * This method is used for exceptions that have been unmarshalled as the
+     * exceptional result of a remote method invocation, so that the
+     * client-side stack trace gets recorded in the exception (while
+     * preserving the server-side stack trace in the exception as well).
+     *
+     * Note that the (somewhat odd) names of this method and the method that
+     * this one internally delegates to are significant because these methods
+     * visually highlight the remote call boundary between the server-side
+     * and the client-side portions to readers of the combined stack trace.
+     */
+    public static void exceptionReceivedFromServer(Throwable t) {
+	__________EXCEPTION_RECEIVED_FROM_SERVER__________(t);
+    }
+
+    private static void __________EXCEPTION_RECEIVED_FROM_SERVER__________(
+	Throwable t)
+    {
+	StackTraceElement[] serverTrace = t.getStackTrace();
+	StackTraceElement[] clientTrace = (new Throwable()).getStackTrace();
+	StackTraceElement[] combinedTrace =
+	    new StackTraceElement[serverTrace.length + clientTrace.length];
+	System.arraycopy(serverTrace, 0, combinedTrace, 0,
+			 serverTrace.length);
+	System.arraycopy(clientTrace, 0, combinedTrace, serverTrace.length,
+			 clientTrace.length);
+	t.setStackTrace(combinedTrace);
+    }
+
+    /**
+     * Clear the stack trace of the given exception by replacing it with
+     * an empty StackTraceElement array, and do the same for all of its
+     * chained causative exceptions.
+     *
+     * This method is used when it is desired for the stack trace data of
+     * an exception to be suppressed before the exception gets marshalled
+     * to a remote virtual machine, perhaps for reasons of confidentiality
+     * or performance.
+     */
+    public static void clearStackTraces(Throwable t) {
+	StackTraceElement[] empty = new StackTraceElement[0];
+	while (t != null) {
+	    t.setStackTrace(empty);
+	    t = t.getCause();
+	}
+    }
+
+    /**
+     * Marshals <code>value</code> to an <code>ObjectOutput</code> stream,
+     * <code>out</code>, using RMI's serialization format for arguments or
+     * return values.  For primitive types, the primitive type's class should
+     * be specified (i.e., for the type <code>int</code>, specify
+     * <code>int.class</code>), and the primitive value should be wrapped in
+     * instances of the appropriate wrapper class, such as
+     * <code>java.lang.Integer</code> or <code>java.lang.Boolean</code>.
+     *
+     * @param	type <code>Class</code> object for the value to be marshalled
+     * @param	value value to marshal
+     * @param	out stream to which the value is marshalled
+     * @throws	IOException if an I/O error occurs marshalling
+     *		the value to the output stream
+     */
+    public static void marshalValue(Class type, Object value, ObjectOutput out)
+	throws IOException
+    {
+	if (type.isPrimitive()) {
+	    if (type == int.class) {
+		out.writeInt(((Integer) value).intValue());
+	    } else if (type == boolean.class) {
+		out.writeBoolean(((Boolean) value).booleanValue());
+	    } else if (type == byte.class) {
+		out.writeByte(((Byte) value).byteValue());
+	    } else if (type == char.class) {
+		out.writeChar(((Character) value).charValue());
+	    } else if (type == short.class) {
+		out.writeShort(((Short) value).shortValue());
+	    } else if (type == long.class) {
+		out.writeLong(((Long) value).longValue());
+	    } else if (type == float.class) {
+		out.writeFloat(((Float) value).floatValue());
+	    } else if (type == double.class) {
+		out.writeDouble(((Double) value).doubleValue());
+	    } else {
+		throw new AssertionError(
+		    "Unrecognized primitive type: " + type);
+	    }
+	} else {
+	    out.writeObject(value);
+	}
+    }
+
+    /**
+     * Unmarshals a value of the specified <code>type</code> from the
+     * <code>ObjectInput</code> stream, <code>in</code>, using RMI's
+     * serialization format for arguments or return values and returns the
+     * result.  For primitive types, the primitive type's class should be
+     * specified (i.e., for the primitive type <code>int</code>, specify
+     * <code>int.class</code>).
+     *
+     * @param	type <code>Class</code> object for the value to be unmarshalled
+     * @param	in stream from which the value is unmarshalled
+     * @return	value unmarshalled from the input stream
+     * @throws	IOException if an I/O error occurs marshalling
+     *		the value to the output stream
+     * @throws	ClassNotFoundException if the <code>type</code>'s
+     *		class could not	be found
+     */
+    public static Object unmarshalValue(Class type, ObjectInput in)
+	throws IOException, ClassNotFoundException
+    {
+	if (type.isPrimitive()) {
+	    if (type == int.class) {
+		return Integer.valueOf(in.readInt());
+	    } else if (type == boolean.class) {
+		return Boolean.valueOf(in.readBoolean());
+	    } else if (type == byte.class) {
+		return Byte.valueOf(in.readByte());
+	    } else if (type == char.class) {
+		return Character.valueOf(in.readChar());
+	    } else if (type == short.class) {
+		return Short.valueOf(in.readShort());
+	    } else if (type == long.class) {
+		return Long.valueOf(in.readLong());
+	    } else if (type == float.class) {
+		return Float.valueOf(in.readFloat());
+	    } else if (type == double.class) {
+		return Double.valueOf(in.readDouble());
+	    } else {
+		throw new AssertionError(
+		    "Unrecognized primitive type: " + type);
+	    }
+	} else {
+	    return in.readObject();
+	}
+    }
+
+    /**
+     * Computes the "method hash" of a remote method, <code>m</code>.  The
+     * method hash is a <code>long</code> containing the first 64 bits of the
+     * SHA digest from the UTF encoded string of the method name followed by
+     * its "method descriptor".  See section 4.3.3 of The Java(TM) Virtual
+     * Machine Specification for the definition of a "method descriptor".
+     *
+     * @param	m remote method
+     * @return	the method hash
+     */
+    private static long computeMethodHash(Method m) {
+	long hash = 0;
+	ByteArrayOutputStream sink = new ByteArrayOutputStream(127);
+	try {
+	    MessageDigest md = MessageDigest.getInstance("SHA");
+	    DataOutputStream out = new DataOutputStream(
+		new DigestOutputStream(sink, md));
+
+	    String s = getMethodNameAndDescriptor(m);
+	    out.writeUTF(s);
+
+	    // use only the first 64 bits of the digest for the hash
+	    out.flush();
+	    byte hasharray[] = md.digest();
+	    for (int i = 0; i < Math.min(8, hasharray.length); i++) {
+		hash += ((long) (hasharray[i] & 0xFF)) << (i * 8);
+	    }
+	} catch (IOException ignore) {
+	    /* can't happen, but be deterministic anyway. */
+	    hash = -1;
+	} catch (NoSuchAlgorithmException complain) {
+	    throw new SecurityException(complain.getMessage());
+	}
+	return hash;
+    }
+
+    /**
+     * Returns the method hash for the method <code>m</code>.  Subsequent
+     * calls to <code>getMethodHash</code> passing the same method argument
+     * should be faster since this method caches internally the result of the
+     * method to method hash mapping.  The method hash is calculated using the
+     * <code>computeMethodHash</code> method.
+     *
+     * @param	m the remote method
+     * @return	the method hash for the method <code>m</code>
+     */
+    public static long getMethodHash(Method m) {
+	Map table = methodToHash_TableCache.getTable(m.getDeclaringClass());
+	Long hash = (Long) table.get(m);
+	return hash.longValue();
+    }
+
+    private static class TableCache extends WeakHashMap {
+	/**
+	 * if true, the tables map methods to method hashes; if false,
+	 * the tables map method hashes to methods
+	 */
+	private boolean mapsMethodToHash;
+
+	public TableCache(boolean mapsMethodToHash) {
+	    super();
+	    this.mapsMethodToHash = mapsMethodToHash;
+	}
+	
+	public Map getTable(Class remoteClass) {
+	    SoftReference[] tableRef;
+
+	    /*
+	     * Method tables for remote classes are cached in a hash table
+	     * using weak references to hold the Class object keys, so that
+	     * the cache does not prevent the class from being unloaded, and
+	     * using soft references to hold the values, so that the computed
+	     * method tables will generally persist while no objects of the
+	     * remote class are exported, but their storage may be reclaimed
+	     * if necessary, and accidental reachability of the remote class
+	     * through its interfaces is avoided.
+	     */
+	    synchronized (this) {
+		/*
+		 * Look up class in cache; add entry if not found.
+		 */
+		tableRef = (SoftReference[]) get(remoteClass);
+		if (tableRef == null) {
+		    tableRef = new SoftReference[] { null };
+		    put(remoteClass, tableRef);
+		}
+	    }
+
+	    /*
+	     * Check cached reference to method table for this class;
+	     * if it is null, go and create the table.
+	     */
+	    synchronized (tableRef) {
+		Map table = null;
+		if (tableRef[0] != null) {
+		    table = (Map) tableRef[0].get();
+		}
+		if (table == null) {
+		    if (mapsMethodToHash) {
+			/*
+			 * REMIND: if we hand out this table directly, via a
+			 * public API, we need to make this map "unmodifiable".
+			 */
+			table = new LazyMethodToHash_Map();
+		    } else {
+			throw new UnsupportedOperationException();
+		    }
+		    tableRef[0] = new SoftReference(table);
+		}
+		return table;
+	    }
+	}
+    }
+
+
+    /**
+     * Verifies that the supplied method has at least one declared exception
+     * type that is RemoteException or one of its superclasses.  If not,
+     * then this method throws IllegalArgumentException.
+     *
+     * @throws IllegalArgumentException if m is an illegal remote method
+     */
+    private static void checkMethod(Method m) {
+	Class[] ex = m.getExceptionTypes();
+	for (int i = 0; i < ex.length; i++) {
+	    if (ex[i].isAssignableFrom(RemoteException.class))
+		return;
+	}
+	throw new IllegalArgumentException(
+	    "illegal remote method encountered: " + m);
+    }
+    
+    private static class LazyMethodToHash_Map extends WeakHashMap {
+
+	public LazyMethodToHash_Map() {
+	    super();
+	}
+
+	public synchronized Object get(Object key) {
+	    Object hash = super.get(key);
+	    if (hash == null) {
+		Method method = (Method) key;
+		hash = Long.valueOf(computeMethodHash(method));
+		put(method, hash);
+	    }
+	    return (Long) hash;
+	}
+    }
+	    
+    /*
+     * The following static methods are related to the creation of the
+     * "method table" for a remote class, which maps method hashes to
+     * the appropriate Method objects for the class's remote methods.
+     */
+
+    /**
+     * Returns a string consisting of the given method's name followed by
+     * its "method descriptor", as appropriate for use in the computation
+     * of the "method hash".
+     *
+     * See section 4.3.3 of The Java(TM) Virtual Machine Specification for
+     * the definition of a "method descriptor".
+     */
+    public static String getMethodNameAndDescriptor(Method m) {
+	StringBuffer desc = new StringBuffer(m.getName());
+	desc.append('(');
+	Class[] paramTypes = m.getParameterTypes();
+	for (int i = 0; i < paramTypes.length; i++) {
+	    desc.append(getTypeDescriptor(paramTypes[i]));
+	}
+	desc.append(')');
+	Class returnType = m.getReturnType();
+	if (returnType == void.class) {	// optimization: handle void here
+	    desc.append('V');
+	} else {
+	    desc.append(getTypeDescriptor(returnType));
+	}
+	return desc.toString();
+    }
+
+    /**
+     * Returns the descriptor of a particular type, as appropriate for either
+     * a parameter type or return type in a method descriptor.
+     */
+    private static String getTypeDescriptor(Class type) {
+	if (type.isPrimitive()) {
+	    if (type == int.class) {
+		return "I";
+	    } else if (type == boolean.class) {
+		return "Z";
+	    } else if (type == byte.class) {
+		return "B";
+	    } else if (type == char.class) {
+		return "C";
+	    } else if (type == short.class) {
+		return "S";
+	    } else if (type == long.class) {
+		return "J";
+	    } else if (type == float.class) {
+		return "F";
+	    } else if (type == double.class) {
+		return "D";
+	    } else if (type == void.class) {
+		return "V";
+	    } else {
+		throw new Error("unrecognized primitive type: " + type);
+	    }
+	} else if (type.isArray()) {
+	    /*
+	     * According to JLS 20.3.2, the getName() method on Class does
+	     * return the virtual machine type descriptor format for array
+	     * classes (only); using that should be quicker than the otherwise
+	     * obvious code:
+	     *
+	     *     return "[" + getTypeDescriptor(type.getComponentType());
+	     */
+	    return type.getName().replace('.', '/');
+	} else {
+	    return "L" + type.getName().replace('.', '/') + ";";
+	}
+    }
+
+    /**
+     * Returns an array containing the remote interfaces implemented
+     * by the given class.
+     *
+     * @throws	IllegalArgumentException if remoteClass implements
+     * 		any illegal remote interfaces
+     * @throws	NullPointerException if remoteClass is null
+     */
+    public static Class[] getRemoteInterfaces(Class remoteClass) {
+	ArrayList list = new ArrayList();
+	getRemoteInterfaces(list, remoteClass);
+	return (Class []) list.toArray(new Class[list.size()]);
+    }
+
+    /**
+     * Fills the given array list with the remote interfaces implemented
+     * by the given class.
+     *
+     * @throws	IllegalArgumentException if the specified class implements
+     * 		any illegal remote interfaces
+     * @throws	NullPointerException if the specified class or list is null
+     */
+    private static void getRemoteInterfaces(ArrayList list, Class cl) {
+	Class superclass = cl.getSuperclass();
+	if (superclass != null) {
+	    getRemoteInterfaces(list, superclass);
+	}
+	
+	Class[] interfaces = cl.getInterfaces();
+	for (int i = 0; i < interfaces.length; i++) {
+	    Class intf = interfaces[i];
+	    /*
+	     * If it is a remote interface (if it extends from
+	     * java.rmi.Remote) and is not already in the list,
+	     * then add the interface to the list.
+	     */
+	    if (Remote.class.isAssignableFrom(intf)) {
+		if (!(list.contains(intf))) {
+		    Method[] methods = intf.getMethods();
+		    for (int j = 0; j < methods.length; j++) {
+			checkMethod(methods[j]);
+		    }
+		    list.add(intf);
+		}
+	    }
+	}
+    }
+
+    /**
+     * Throws IllegalArgumentException if any superinterface of c declares a
+     * method with the same name and parameter types as m that does not
+     * declare RemoteException or a superclass in its throws clause, or if
+     * any superinterface of c has its name in prohibitedProxyInterfaces.
+     */
+    public static void checkProxyRemoteMethod(Class c, Method m) {
+	WeakIdentityMap map;
+	synchronized (proxyRemoteMethodCache) {
+	    SoftReference ref = (SoftReference) proxyRemoteMethodCache.get(c);
+	    map = (ref == null) ? null : (WeakIdentityMap) ref.get();
+	    if (map == null && ref != null) {
+		map = new WeakIdentityMap();
+		proxyRemoteMethodCache.put(c, new SoftReference(map));
+	    }
+	}
+	if (map == null) {
+	    checkProhibitedProxyInterfaces(c);
+	    synchronized (proxyRemoteMethodCache) {
+		SoftReference ref =
+		    (SoftReference) proxyRemoteMethodCache.get(c);
+		map = (ref == null) ? null : (WeakIdentityMap) ref.get();
+		if (map == null) {
+		    map = new WeakIdentityMap();
+		    proxyRemoteMethodCache.put(c, new SoftReference(map));
+		}
+	    }
+	}
+	synchronized (map) {
+	    if (map.get(m) != null) {
+		return;
+	    }
+	}
+	checkExceptions(c, m.getName(), m.getParameterTypes());
+	synchronized (map) {
+	    map.put(m, Boolean.TRUE);
+	}
+    }
+
+    /**
+     * Throws IllegalArgumentException if any superinterface of c declares a
+     * method with the given name and parameter types that does not declare
+     * RemoteException or a superclass in its throws clause.
+     */
+    private static void checkExceptions(Class c, String name, Class[] types) {
+	Class[] ifaces = c.getInterfaces();
+	for (int i = ifaces.length; --i >= 0; ) {
+	    try {
+		checkMethod(ifaces[i].getMethod(name, types));
+		checkExceptions(ifaces[i], name, types);
+	    } catch (NoSuchMethodException e) {
+	    }
+	}
+    }
+
+    /**
+     * Returns collection of prohibited proxy interfaces read from resources.
+     */
+    private static Collection getProhibitedProxyInterfaces() {
+	Collection names = new HashSet();
+	names.add("javax.management.MBeanServerConnection");
+	Enumeration resources;
+	try {
+	    resources = ClassLoader.getSystemResources(
+					  prohibitedProxyInterfacesResource);
+	} catch (IOException e) {
+	    throw new ExceptionInInitializerError(
+			new IOException(
+			     "problem getting resources: " +
+			     prohibitedProxyInterfacesResource).initCause(e));
+	}
+	while (resources.hasMoreElements()) {
+	    URL url = (URL) resources.nextElement();
+	    try {
+		InputStream in = url.openStream();
+		try {
+		    BufferedReader r =
+			new BufferedReader(new InputStreamReader(in, "utf-8"));
+		    while (true) {
+			String s = r.readLine();
+			if (s == null) {
+			    break;
+			}
+			int i = s.indexOf('#');
+			if (i >= 0) {
+			    s = s.substring(0, i);
+			}
+			s = s.trim();
+			int n = s.length();
+			if (n == 0) {
+			    continue;
+			}
+			char prev = '.';
+			for (i = 0; i < n; i++) {
+			    char c = s.charAt(i);
+			    if (prev == '.' ?
+				!Character.isJavaIdentifierStart(c) :
+				!(Character.isJavaIdentifierPart(c) ||
+				  (c == '.' && i < n - 1)))
+			    {
+				throw new ExceptionInInitializerError(
+					      "illegal interface name in " +
+					      url + ": " + s);
+			    }
+			    prev = c;
+			}
+			names.add(s);
+		    }
+		} finally {
+		    try {
+			in.close();
+		    } catch (IOException e) {
+		    }
+		}
+	    } catch (IOException e) {
+		throw new ExceptionInInitializerError(
+		      new IOException("problem reading " + url).initCause(e));
+	    }
+	}
+	return names;
+    }
+
+    /**
+     * Throws IllegalArgumentException if any superinterface of c has its
+     * name in prohibitedProxyInterfaces.
+     */
+    private static void checkProhibitedProxyInterfaces(Class c) {
+	Class[] ifaces = c.getInterfaces();
+	for (int i = ifaces.length; --i >= 0; ) {
+	    String name = ifaces[i].getName();
+	    if (prohibitedProxyInterfaces.contains(name)) {
+		throw new IllegalArgumentException(
+		       "prohibited proxy interface encountered: " + name);
+	    }
+	    checkProhibitedProxyInterfaces(ifaces[i]);
+	}
+    }
+
+    /**
+     * Returns the binary name of the given type without package
+     * qualification.  Nested types are treated no differently from
+     * top-level types, so for a nested type, the returned name will
+     * still be qualified with the simple name of its enclosing
+     * top-level type (and perhaps other enclosing types), the
+     * separator will be '$', etc.
+     **/
+    public static String getUnqualifiedName(Class c) {
+	String binaryName = c.getName();
+	return binaryName.substring(binaryName.lastIndexOf('.') + 1);
+    }
+
+    /**
+     * Returns true either if both arguments are null or if an
+     * invocation of Object.equals on "subject" with "object" as the
+     * argument returns true; returns false otherwise;
+     **/
+    public static boolean equals(Object subject, Object object) {
+	return subject == null ? object == null : subject.equals(object);
+    }
+
+    /**
+     * Returns true either if both arguments are null or if both
+     * arguments refer to objects of the same class and an invocation
+     * of Object.equals on "subject" with "object" as the argument
+     * returns true; returns false otherwise.
+     *
+     * This method is used to compare to possibly-null references for
+     * object equality when neither object's class is trusted, with
+     * the restriction that only objects of the same class can be
+     * considered equal.
+     **/
+    public static boolean sameClassAndEquals(Object subject, Object object) {
+	return subject == null ? object == null :
+	    object != null &&
+	    subject.getClass() == object.getClass() &&
+	    subject.equals(object);
+    }
+
+    /**
+     * Returns true either if both arguments are null of if "subject"
+     * is an instance of TrustEquivalence and an invocation of
+     * TrustEquivalence.checkTrustEquivalence on "subject" with
+     * "object" as the argument returns true; returns false otherwise.
+     **/
+    public static boolean checkTrustEquivalence(Object subject,
+						Object object)
+    {
+	return subject == null ? object == null :
+	    subject instanceof TrustEquivalence &&
+	    ((TrustEquivalence) subject).checkTrustEquivalence(object);
+    }
+
+    /**
+     * Returns true if proxy2 is a generated Proxy (proxy1 is assumed to
+     * be one) and the classes of both proxies implement the same ordered
+     * list of interfaces, and returns false otherwise.
+     */
+    public static boolean sameProxyClass(Object proxy1, Object proxy2) {
+	return (proxy1.getClass() == proxy2.getClass() ||
+		(Proxy.isProxyClass(proxy2.getClass()) &&
+		 equalInterfaces(proxy1, proxy2)));
+    }
+
+    /**
+     * Returns true if the interfaces implemented by obj1's class
+     * are the same (and in the same order) as obj2's class.
+     */
+    public static boolean equalInterfaces(Object obj1, Object obj2) {
+	Class[] intf1 = obj1.getClass().getInterfaces();
+	Class[] intf2 = obj2.getClass().getInterfaces();
+	if (intf1.length != intf2.length) {
+	    return false;
+	} else {
+	    for (int i = 0; i < intf1.length; i++) {
+		if (intf1[i] != intf2[i]) {
+		    return false;
+		}
+	    }
+	    return true;
+	}
+    }
+    
+    public static void populateContext(Collection context, InetAddress addr) {
+	if (context == null) {
+	    throw new NullPointerException("context is null");
+	}
+	if (addr != null) {
+	    context.add(new ClientHostImpl(addr));
+	}
+    }
+    
+    public static void populateContext(Collection context, Subject s) {
+	if (context == null) {
+	    throw new NullPointerException("context is null");
+	}
+	context.add(new ClientSubjectImpl(s));
+    }
+
+    public static void populateContext(Collection context, boolean integrity) {
+	if (context == null) {
+	    throw new NullPointerException("context is null");
+	}
+	context.add(new IntegrityEnforcementImpl(integrity));
+    }
+
+    private static class ClientHostImpl
+    	implements ClientHost
+    {
+	private final InetAddress addr;
+	public ClientHostImpl(InetAddress addr) { this.addr = addr; }
+	public InetAddress getClientHost() { return addr; }
+    }
+
+    private static class ClientSubjectImpl
+    	implements ClientSubject
+    {
+	private final Subject s;
+	private static final Permission getClientSubjectPerm =
+	    new ContextPermission("net.jini.io.context.ClientSubject.getClientSubject");
+
+	public ClientSubjectImpl(Subject s) { this.s = s; }
+	public Subject getClientSubject() {
+	    SecurityManager sm = System.getSecurityManager();
+	    if (sm != null) {
+		sm.checkPermission(getClientSubjectPerm);
+	    }
+	    return s;
+	}
+    }
+
+    private static class IntegrityEnforcementImpl
+    	implements IntegrityEnforcement
+    {
+	private final boolean integrity;
+	public IntegrityEnforcementImpl(boolean integrity) {
+	    this.integrity = integrity;
+	}
+	public boolean integrityEnforced() { return integrity; }
+    }
+
+    public static InetAddress getClientHost() throws ServerNotActiveException {
+	ClientHost ch = (ClientHost)
+	    ServerContext.getServerContextElement(ClientHost.class);
+	return (ch != null) ? ch.getClientHost() : null;
+    }
+
+    public static String getClientHostString()
+	throws ServerNotActiveException
+    {
+	InetAddress addr = getClientHost();
+	return (addr != null) ? addr.toString() : null;
+    }
+
+    public static Subject getClientSubject() throws ServerNotActiveException {
+	ClientSubject cs = (ClientSubject)
+	    ServerContext.getServerContextElement(ClientSubject.class);
+	return (cs != null) ? cs.getClientSubject() : null;
+    }
+
+    /**
+     * Check for permission to access the package of the specified class.
+     *
+     * @throws SecurityException if a security manager exists and invoking
+     * its <code>checkPackageAccess</code> method with the package name of
+     * the specified class throws a <code>SecurityException</code>
+     */
+    public static void checkPackageAccess(Class type) {
+	SecurityManager security = System.getSecurityManager();
+	if (security != null) {
+	    String name = type.getName();
+	    int i = name.lastIndexOf('.');
+	    if (i != -1) {
+		security.checkPackageAccess(name.substring(0, i));
+	    }
+	}
+    }
+}

Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mahalo/TxnManagerImplInitializer.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mahalo/TxnManagerImplInitializer.java?rev=1593493&r1=1593492&r2=1593493&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mahalo/TxnManagerImplInitializer.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mahalo/TxnManagerImplInitializer.java Fri May  9 07:03:18 2014
@@ -65,13 +65,15 @@ import org.apache.river.impl.thread.Name
  */
 class TxnManagerImplInitializer {
     /* Default tuning parameters for thread pool */
-    int settlerthreads = 150;
+    int cores = Runtime.getRuntime().availableProcessors();
+    int settlerthreads = 15*cores;
     long settlertimeout = 1000 * 15;
     float settlerload = 1.0F;
-    int taskthreads = 50;
+    int taskthreads = 5*cores;
     long tasktimeout = 1000 * 15;
     float taskload = 1.0F;
-    ConcurrentMap<Long, TxnManagerTransaction> txns = new ConcurrentHashMap<Long, TxnManagerTransaction>();
+    ConcurrentMap<Long, TxnManagerTransaction> txns =
+            new ConcurrentHashMap<Long, TxnManagerTransaction>();
     /* Retrieve values from properties.          */
     ActivationSystem activationSystem = null;
     boolean activationPrepared = false;

Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mercury/MailboxImpl.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mercury/MailboxImpl.java?rev=1593493&r1=1593492&r2=1593493&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mercury/MailboxImpl.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mercury/MailboxImpl.java Fri May  9 07:03:18 2014
@@ -3777,15 +3777,13 @@ class MailboxImpl implements MailboxBack
     /** Registration expiration thread code */
     private class ExpirationThread extends InterruptedStatusThread implements TimeConstants {
 
-	/** Create a daemon thread and start it */
 	public ExpirationThread() {
 	    super("ExpirationThread");
-	    setDaemon(true);
+	    setDaemon(false);
             if (expirationLogger.isLoggable(Level.FINEST)) {
                 expirationLogger.log(Level.FINEST,
 		    "ExpirationThread started ...");
             }
-            //start();
 	}
 
 	/** 
@@ -4952,11 +4950,13 @@ class MailboxImpl implements MailboxBack
      */
     private class SnapshotThread extends InterruptedStatusThread {
 
-	/** Create a daemon thread */
+        /**
+         * Ensure thread is non daemon to avoid jvm terminating it during
+         * a snapshot.
+         */
 	public SnapshotThread() {
 	    super("SnapshotThread");
-	    setDaemon(true);
-//	    start();
+	    setDaemon(false);
 	}
 
 	public void run() {