Skip to content

Commit

Permalink
[RESTEASY-2157] Fixing issue by using a composite proxy classloader
Browse files Browse the repository at this point in the history
  • Loading branch information
asoldano committed Mar 13, 2019
1 parent 0f8691a commit 06e4c69
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 5 deletions.
Expand Up @@ -12,12 +12,19 @@
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.SecureClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.NoSuchElementException;
import java.util.Set;

public class ProxyBuilder<T>
Expand Down Expand Up @@ -82,7 +89,14 @@ else if (httpMethods == null) {
// infrastructure had some problems without this.
clientProxy.setClazz(iface);

return (T) Proxy.newProxyInstance(config.getLoader(), intfs, clientProxy);
ClassLoader cl = config.getLoader();
try {
cl.loadClass(iface.getName());
} catch (Throwable t) {
cl = new DelegateClassLoader(iface.getClassLoader(), cl);
}

return (T) Proxy.newProxyInstance(cl, intfs, clientProxy);
}

private static <T> ClientInvoker createClientInvoker(Class<T> clazz, Method method, ResteasyWebTarget base, ProxyConfig config)
Expand Down Expand Up @@ -153,5 +167,107 @@ public T build()
}


public static class DelegateClassLoader extends SecureClassLoader
{
private final ClassLoader delegate;

private final ClassLoader parent;

public DelegateClassLoader(final ClassLoader delegate, final ClassLoader parent)
{
super(parent);
this.delegate = delegate;
this.parent = parent;
}

/** {@inheritDoc} */
@Override
public Class<?> loadClass(final String className) throws ClassNotFoundException
{
if (parent != null)
{
try
{
return parent.loadClass(className);
}
catch (ClassNotFoundException cnfe)
{
//NOOP, use delegate
}
}
return delegate.loadClass(className);
}

/** {@inheritDoc} */
@Override
public URL getResource(final String name)
{
URL url = null;
if (parent != null)
{
url = parent.getResource(name);
}
return (url == null) ? delegate.getResource(name) : url;
}

/** {@inheritDoc} */
@Override
public Enumeration<URL> getResources(final String name) throws IOException
{
final ArrayList<Enumeration<URL>> foundResources = new ArrayList<Enumeration<URL>>();

foundResources.add(delegate.getResources(name));
if (parent != null)
{
foundResources.add(parent.getResources(name));
}

return new Enumeration<URL>()
{
private int position = foundResources.size() - 1;

public boolean hasMoreElements()
{
while (position >= 0)
{
if (foundResources.get(position).hasMoreElements())
{
return true;
}
position--;
}
return false;
}

public URL nextElement()
{
while (position >= 0)
{
try
{
return (foundResources.get(position)).nextElement();
}
catch (NoSuchElementException e)
{
}
position--;
}
throw new NoSuchElementException();
}
};
}

/** {@inheritDoc} */
@Override
public InputStream getResourceAsStream(final String name)
{
InputStream is = null;
if (parent != null)
{
is = parent.getResourceAsStream(name);
}
return (is == null) ? delegate.getResourceAsStream(name) : is;
}
}

}
Expand Up @@ -15,7 +15,6 @@
import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;

Expand All @@ -33,7 +32,6 @@ public static Archive<?> deploySimpleResource()
}

@Test
@Ignore("RESTEASY-2157")
public void testNoTCCL() throws Exception
{
ResteasyClient client = (ResteasyClient) ClientBuilder.newClient();
Expand Down
Expand Up @@ -6,8 +6,8 @@
import javax.ws.rs.QueryParam;
import javax.ws.rs.client.ClientBuilder;

import org.jboss.resteasy.client.jaxrs.ProxyBuilder;
import org.jboss.resteasy.client.jaxrs.ResteasyClient;
import org.jboss.resteasy.client.jaxrs.internal.proxy.ProxyBuilderImpl;
import org.jboss.resteasy.test.core.smoke.resource.ResourceWithInterfaceSimpleClient;

@Path("/cl")
Expand All @@ -25,7 +25,7 @@ public String test(@QueryParam("param") String targetBase) throws Exception
try
{
//replace the TCCL with the classloader from the resteasy-client module
Thread.currentThread().setContextClassLoader(ProxyBuilderImpl.class.getClassLoader());
Thread.currentThread().setContextClassLoader(ProxyBuilder.class.getClassLoader());
//try building the proxy; the TCCL does not have visibility over the deployment classes
ResourceWithInterfaceSimpleClient proxy = client.target(targetBase)
.proxyBuilder(ResourceWithInterfaceSimpleClient.class).build();
Expand Down

0 comments on commit 06e4c69

Please sign in to comment.