You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by dk...@apache.org on 2012/11/19 21:40:51 UTC

svn commit: r1411397 - in /cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http: CXFAuthenticator.java ReferencingAuthenticator.java

Author: dkulp
Date: Mon Nov 19 20:40:51 2012
New Revision: 1411397

URL: http://svn.apache.org/viewvc?rev=1411397&view=rev
Log:
[CXF-4529] Make an attempt at a workaround for the issue of hte authenticator holding onto the classloader.

Added:
    cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/ReferencingAuthenticator.java
Modified:
    cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/CXFAuthenticator.java

Modified: cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/CXFAuthenticator.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/CXFAuthenticator.java?rev=1411397&r1=1411396&r2=1411397&view=diff
==============================================================================
--- cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/CXFAuthenticator.java (original)
+++ cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/CXFAuthenticator.java Mon Nov 19 20:40:51 2012
@@ -19,13 +19,16 @@
 
 package org.apache.cxf.transport.http;
 
+import java.io.InputStream;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
 import java.net.Authenticator;
 import java.net.PasswordAuthentication;
+import java.net.URL;
+import java.net.URLClassLoader;
 
 import org.apache.cxf.common.util.ReflectionUtil;
+import org.apache.cxf.helpers.IOUtils;
 import org.apache.cxf.message.Exchange;
 import org.apache.cxf.message.Message;
 import org.apache.cxf.phase.PhaseInterceptorChain;
@@ -35,30 +38,43 @@ import org.apache.cxf.transport.Conduit;
  * 
  */
 public class CXFAuthenticator extends Authenticator {
-    static Authenticator wrapped;
     static boolean setup;
+    private static final CXFAuthenticator INSTANCE = new CXFAuthenticator();
     
     
     public CXFAuthenticator() {
-        try {
+    }
+
+    public static synchronized void addAuthenticator() { 
+        if (!setup) {
+            Authenticator wrapped = null;
             for (final Field f : Authenticator.class.getDeclaredFields()) {
                 if (f.getType().equals(Authenticator.class)) {
                     ReflectionUtil.setAccessible(f);
-
-                    wrapped = (Authenticator)f.get(null);
+                    try {
+                        wrapped = (Authenticator)f.get(null);
+                    } catch (Exception e) {
+                        //ignore
+                    }
                 }
             }
-        } catch (Throwable ex) {
-            //ignore
-        }
-    }
-
-    public static synchronized void addAuthenticator() { 
-        if (!setup) {
+            
             try {
-                Authenticator.setDefault(new CXFAuthenticator());
+                InputStream ins = ReferencingAuthenticator.class.getResourceAsStream("ReferencingAuthenticator.class");
+                final byte b[] = IOUtils.readBytesFromStream(ins);
+                ClassLoader loader = new URLClassLoader(new URL[0], ClassLoader.getSystemClassLoader());
+                Method m = ClassLoader.class.getDeclaredMethod("defineClass", String.class, 
+                                                               byte[].class, Integer.TYPE, Integer.TYPE);
+                ReflectionUtil.setAccessible(m).invoke(loader, ReferencingAuthenticator.class.getName(),
+                                                       b, 0, b.length);
+                Class<?> cls = loader.loadClass(ReferencingAuthenticator.class.getName());
+                Authenticator auth = (Authenticator)cls.getConstructor(Authenticator.class, Authenticator.class)
+                    .newInstance(INSTANCE, wrapped);
+                
+                Authenticator.setDefault(auth);
             } catch (Throwable t) {
                 //ignore
+                t.printStackTrace();
             }
             setup = true;
         }
@@ -66,24 +82,6 @@ public class CXFAuthenticator extends Au
     
     protected PasswordAuthentication getPasswordAuthentication() { 
         PasswordAuthentication auth = null;
-        if (wrapped != null) {
-            try {
-                for (final Field f : Authenticator.class.getDeclaredFields()) {
-                    if (!Modifier.isStatic(f.getModifiers())) {
-                        ReflectionUtil.setAccessible(f);
-                        f.set(wrapped, f.get(this));
-                    }
-                }
-                final Method m = Authenticator.class.getDeclaredMethod("getPasswordAuthentication");
-                ReflectionUtil.setAccessible(m);
-                auth = (PasswordAuthentication)m.invoke(wrapped);
-            } catch (Throwable t) {
-                //ignore
-            }
-        }
-        if (auth != null) {
-            return auth;
-        }
         Message m = PhaseInterceptorChain.getCurrentMessage();
         if (m != null) {
             Exchange exchange = m.getExchange();

Added: cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/ReferencingAuthenticator.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/ReferencingAuthenticator.java?rev=1411397&view=auto
==============================================================================
--- cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/ReferencingAuthenticator.java (added)
+++ cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/ReferencingAuthenticator.java Mon Nov 19 20:40:51 2012
@@ -0,0 +1,79 @@
+/**
+ * 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 org.apache.cxf.transport.http;
+
+import java.lang.ref.SoftReference;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.net.Authenticator;
+import java.net.PasswordAuthentication;
+
+public class ReferencingAuthenticator extends Authenticator {
+    SoftReference<Authenticator> auth;
+    Authenticator wrapped;
+    public ReferencingAuthenticator(Authenticator cxfauth, Authenticator wrapped) {
+        this.auth = new SoftReference<Authenticator>(cxfauth);
+        this.wrapped = wrapped;
+    }
+    @Override
+    protected PasswordAuthentication getPasswordAuthentication() {
+        PasswordAuthentication pauth = null;
+        if (wrapped != null) {
+            try {
+                pauth = tryWith(wrapped);
+                if (pauth != null) {
+                    return pauth;
+                }
+            } catch (Exception e) {
+                pauth = null;
+            }
+        }
+        Authenticator cxfauth = auth.get();
+        if (cxfauth == null) {
+            try {
+                Authenticator.setDefault(wrapped);
+            } catch (Throwable t) {
+                //ignore
+            }
+        } else {
+            try {
+                pauth = tryWith(cxfauth);
+            } catch (Exception e1) {
+                pauth = null;
+            }
+        }
+        return pauth;
+    }  
+    PasswordAuthentication tryWith(Authenticator a) throws Exception {
+        if (a == null) {
+            return null;
+        }
+        for (final Field f : Authenticator.class.getDeclaredFields()) {
+            if (!Modifier.isStatic(f.getModifiers())) {
+                f.setAccessible(true);
+                Object o = f.get(this);
+                f.set(a, o);
+            }
+        } 
+        final Method m = Authenticator.class.getDeclaredMethod("getPasswordAuthentication");
+        m.setAccessible(true);
+        return (PasswordAuthentication)m.invoke(a);
+    }
+}
\ No newline at end of file