[
http://jira.jboss.com/jira/browse/JBREM-900?page=comments#action_12400390 ]
Ron Sigal commented on JBREM-900:
---------------------------------
A WeakHashMap has been added to org.jboss.remoting.MicroRemoteClientInvoker for caching
unmarshallers, keyed on the current thread context classloader. This change should solve
the problem described in the forum thread, since the Application Server should set the
context classloader to the EAR's classloader before passing control to any ejbs, mdbs,
etc., in the EAR.
Each unmarshaller has an org.jboss.remoting.loading.RemotingClassLoader, which has a
reference to the classloader that loaded jboss-remoting.jar and a reference to the context
classloader. There's no problem holding on to the former, since Remoting classes will
stay loaded throughout the life of the Application Server instance. However, we don't
want to hold on to the context classloader. One option would be for the unmarshaller to
store the reference to its RemotingClassLoader in a WeakReference. However, several
unmarshallers derived from
org.jboss.remoting.marshal.serializable.SerializableUnMarshaller, including
org.jboss.invocation.unified.marshall.InvocationUnMarshaller in the Application Server,
refer directly to the instance variable SerializableUnMarshaller.customClassLoader, which
holds the reference to the RemotingClassLoader. Rather than risk breaking source code
compatibility, an alternative solution is used:
* at the beginning of each invocation, MicroRemoteClientInvoker retrieves the
RemotingClassLoader from a cached unmarshaller and calls
RemotingClassLoader.setUserClassLoader() to set the reference to the context classloader,
and
* at then end of each invocation, MicroRemoteClientInvoker calls
RemotingClassLoader.unsetUserClassLoader() to set the reference to null.
However, the situation is complicated by the fact that multiple threads can share a
context classloader, so that they would be using the same unmarshaller while making
simultaneous invocations to the same server. Therefore, RemotingClassLoader maintains a
reference count of the number of invocations it is involved in. It sets the context
classloader reference only when the count is zero, and it sets the reference to null only
when the count goes to zero.
The resulting code is somewhat more complex than simply recreating the unmarshaller for
each invocation, but it is also faster. Tests show that caching unmarshallers is
approximately 2.14 times faster than recreating them.
ClassCastExceptions when two apps in jboss make concurrent calls to a
remote jboss
----------------------------------------------------------------------------------
Key: JBREM-900
URL:
http://jira.jboss.com/jira/browse/JBREM-900
Project: JBoss Remoting
Issue Type: Bug
Security Level: Public(Everyone can see)
Affects Versions: 2.2.2.SP2, 2.2.2.SP1, 2.2.2.GA, 2.2.1.GA
Environment: Linux, AMD 64
Reporter: Paul Mark Skittone
Assigned To: Ron Sigal
Fix For: 2.4.0.CR1 (Pinto)
When two EJB3 apps (isolated, with call-by-value) running in the same jboss make
concurrent calls to a second jboss instance, one of the two apps often uses the other
app's ClassLoader, causing ClassCastExceptions.
Detailed discussion and potential code changes to address the concurrency problem are
included in the forum thread.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://jira.jboss.com/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira