Author: dkulp Date: Tue Nov 20 21:07:59 2012 New Revision: 1411865 URL: http://svn.apache.org/viewvc?rev=1411865&view=rev Log: Merged revisions 1411852 via git cherry-pick from https://svn.apache.org/repos/asf/cxf/branches/2.6.x-fixes
........ r1411852 | dkulp | 2012-11-20 15:50:02 -0500 (Tue, 20 Nov 2012) | 10 lines Merged revisions 1411397 via git cherry-pick from https://svn.apache.org/repos/asf/cxf/trunk ........ r1411397 | dkulp | 2012-11-19 15:40:51 -0500 (Mon, 19 Nov 2012) | 2 lines [CXF-4529] Make an attempt at a workaround for the issue of hte authenticator holding onto the classloader. ........ ........ Added: cxf/branches/2.5.x-fixes/rt/transports/http/src/main/java/org/apache/cxf/transport/http/ReferencingAuthenticator.java Modified: cxf/branches/2.5.x-fixes/rt/transports/http/src/main/java/org/apache/cxf/transport/http/CXFAuthenticator.java Modified: cxf/branches/2.5.x-fixes/rt/transports/http/src/main/java/org/apache/cxf/transport/http/CXFAuthenticator.java URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/rt/transports/http/src/main/java/org/apache/cxf/transport/http/CXFAuthenticator.java?rev=1411865&r1=1411864&r2=1411865&view=diff ============================================================================== --- cxf/branches/2.5.x-fixes/rt/transports/http/src/main/java/org/apache/cxf/transport/http/CXFAuthenticator.java (original) +++ cxf/branches/2.5.x-fixes/rt/transports/http/src/main/java/org/apache/cxf/transport/http/CXFAuthenticator.java Tue Nov 20 21:07:59 2012 @@ -19,12 +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; @@ -34,29 +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 { - for (Field f : Authenticator.class.getDeclaredFields()) { - if (f.getType().equals(Authenticator.class)) { - f.setAccessible(true); - wrapped = (Authenticator)f.get(null); - } - } - } catch (Throwable ex) { - //ignore - } } 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); + try { + wrapped = (Authenticator)f.get(null); + } catch (Exception e) { + //ignore + } + } + } + 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; } @@ -64,24 +82,6 @@ public class CXFAuthenticator extends Au protected PasswordAuthentication getPasswordAuthentication() { PasswordAuthentication auth = null; - if (wrapped != null) { - try { - for (Field f : Authenticator.class.getDeclaredFields()) { - if (!Modifier.isStatic(f.getModifiers())) { - f.setAccessible(true); - f.set(wrapped, f.get(this)); - } - } - Method m = Authenticator.class.getDeclaredMethod("getPasswordAuthentication"); - m.setAccessible(true); - 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/branches/2.5.x-fixes/rt/transports/http/src/main/java/org/apache/cxf/transport/http/ReferencingAuthenticator.java URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/rt/transports/http/src/main/java/org/apache/cxf/transport/http/ReferencingAuthenticator.java?rev=1411865&view=auto ============================================================================== --- cxf/branches/2.5.x-fixes/rt/transports/http/src/main/java/org/apache/cxf/transport/http/ReferencingAuthenticator.java (added) +++ cxf/branches/2.5.x-fixes/rt/transports/http/src/main/java/org/apache/cxf/transport/http/ReferencingAuthenticator.java Tue Nov 20 21:07:59 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
