You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by sc...@apache.org on 2008/05/01 15:59:22 UTC

svn commit: r652524 - /webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/client/async/AsyncResponse.java

Author: scheu
Date: Thu May  1 06:59:21 2008
New Revision: 652524

URL: http://svn.apache.org/viewvc?rev=652524&view=rev
Log:
Refactored the ClassLoader Checking
Contributor: Dustin Amrhein and Rich Scheuerle
The AsyncResponse object must ensure that the classloader used for unmarshalling is acceptable with the
current classloader of the client application.  If it is not an error is thrown (failure to throw an error leads
to hard to diagnose ClassCastException errors in the client's application).

Modified:
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/client/async/AsyncResponse.java

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/client/async/AsyncResponse.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/client/async/AsyncResponse.java?rev=652524&r1=652523&r2=652524&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/client/async/AsyncResponse.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/client/async/AsyncResponse.java Thu May  1 06:59:21 2008
@@ -73,11 +73,6 @@
     private CountDownLatch latch;
     private boolean cacheValid = false;
     private Object cachedObject = null;
-
-    // we need to ensure the classloader used under onComplete (where the response object is unmarshalled) is
-    // the same classloader as the one used by the client app, otherwise we'll get a strange ClassCastException
-    // This object is just a cache object.
-    private ClassLoader classLoader = null;
     
     // The response business object to be returned
     private Object responseObject = null;
@@ -92,14 +87,13 @@
     }
 
     protected void onError(Throwable flt, MessageContext mc, ClassLoader cl) {
-        ClassLoader origClassLoader = (ClassLoader)AccessController.doPrivileged(new PrivilegedAction() {
+        ClassLoader contextCL = (ClassLoader)AccessController.doPrivileged(new PrivilegedAction() {
             public Object run() {
                 return Thread.currentThread().getContextClassLoader();
             }
         });
-        setThreadClassLoader(cl);
         onError(flt, mc);
-        setThreadClassLoader(origClassLoader);
+        checkClassLoader(cl, contextCL);
     }
     
     protected void onError(Throwable flt, MessageContext faultCtx) {
@@ -128,37 +122,63 @@
         }
     }
     
-    private void setThreadClassLoader(final ClassLoader cl) {
-        if (this.classLoader != null) {
-            if (!this.classLoader.getClass().equals(cl.getClass())) {
-                throw ExceptionFactory.makeWebServiceException(Messages.getMessage("threadClsLoaderErr",
-                		cl.getClass().toString(),this.classLoader.getClass().toString()));
-            }
-        }
-        else {
-            if (log.isDebugEnabled()) {
-                log.debug("Setting up the thread's ClassLoader");
-                log.debug(cl.toString());
+    /**
+     * Check for a valid relationship between unmarshalling classloader and
+     * Application's current context classloader
+     * @param cl
+     * @param contextCL
+     */
+    private void checkClassLoader(final ClassLoader cl, final ClassLoader contextCL) {
+        // Ensure that the classloader (cl) used for unmarshalling is the same
+        // or a parent of the current context classloader.  Otherwise 
+        // ClassCastExceptions can occur
+        if(log.isDebugEnabled()) {
+            log.debug("AsyncResponse ClassLoader is:");
+            log.debug(cl.toString());
+        }
+        if (cl.equals(contextCL)) {
+            if(log.isDebugEnabled()) {
+                log.debug("AsyncResponse ClassLoader matches Context ClassLoader");
             }
-            this.classLoader = cl;
-            AccessController.doPrivileged(new PrivilegedAction() {
-                public Object run() {
-                    Thread.currentThread().setContextClassLoader(cl);
-                    return null;
+            return;
+        } else {
+            if(log.isDebugEnabled()) {
+                log.debug("Context ClassLoader is:");
+                log.debug(contextCL.toString());
+            }
+            ClassLoader parent = getParentClassLoader(contextCL);
+            while(parent != null) {
+                if (parent.equals(cl)) {
+                    return;
+                }
+                if(log.isDebugEnabled()) {
+                    log.debug("AsyncResponse ClassLoader is an ancestor of the Context ClassLoader");
                 }
-            });
+                parent = getParentClassLoader(parent);
+            }
         }
+        throw ExceptionFactory.
+          makeWebServiceException(Messages.getMessage("threadClsLoaderErr",
+                   contextCL.getClass().toString(), cl.getClass().toString()));
+    }
+    
+    
+    ClassLoader getParentClassLoader(final ClassLoader cl) {
+        return (ClassLoader) AccessController.doPrivileged(new PrivilegedAction() {
+            public Object run() {
+                return cl.getParent();
+            }
+        });
     }
     
     protected void onComplete(MessageContext mc, ClassLoader cl) {
-        ClassLoader origClassLoader = (ClassLoader)AccessController.doPrivileged(new PrivilegedAction() {
+        ClassLoader contextCL = (ClassLoader)AccessController.doPrivileged(new PrivilegedAction() {
             public Object run() {
                 return Thread.currentThread().getContextClassLoader();
             }
         });
-        setThreadClassLoader(cl);
         onComplete(mc);
-        setThreadClassLoader(origClassLoader);
+        checkClassLoader(cl, contextCL);
     }
 
     protected void onComplete(MessageContext mc) {



---------------------------------------------------------------------
To unsubscribe, e-mail: axis-cvs-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-cvs-help@ws.apache.org