fix issue 508 -- consider method return type when deciding whether to bridge. patch contributed by stuart.
git-svn-id: https://google-guice.googlecode.com/svn/trunk@1374 d779f126-a31b-0410-b53b-1d3aecad763e
diff --git a/core/src/com/google/inject/internal/BytecodeGen.java b/core/src/com/google/inject/internal/BytecodeGen.java
index 6f24ea8..1bdfb75 100644
--- a/core/src/com/google/inject/internal/BytecodeGen.java
+++ b/core/src/com/google/inject/internal/BytecodeGen.java
@@ -258,9 +258,17 @@
return SAME_PACKAGE;
}
- Class[] parameterTypes = member instanceof Constructor
- ? ((Constructor) member).getParameterTypes()
- : ((Method) member).getParameterTypes();
+ Class[] parameterTypes;
+ if (member instanceof Constructor) {
+ parameterTypes = ((Constructor) member).getParameterTypes();
+ } else {
+ Method method = (Method) member;
+ if (forType(method.getReturnType()) == SAME_PACKAGE) {
+ return SAME_PACKAGE;
+ }
+ parameterTypes = method.getParameterTypes();
+ }
+
for (Class<?> type : parameterTypes) {
if (forType(type) == SAME_PACKAGE) {
return SAME_PACKAGE;
diff --git a/core/test/com/googlecode/guice/BytecodeGenTest.java b/core/test/com/googlecode/guice/BytecodeGenTest.java
index ddba099..054bd38 100644
--- a/core/test/com/googlecode/guice/BytecodeGenTest.java
+++ b/core/test/com/googlecode/guice/BytecodeGenTest.java
@@ -26,6 +26,7 @@
import java.io.File;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
+import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
@@ -55,6 +56,17 @@
}
};
+ private final Module noopInterceptorModule = new AbstractModule() {
+ protected void configure() {
+ bindInterceptor(any(), any(), new MethodInterceptor() {
+ public Object invoke(MethodInvocation chain)
+ throws Throwable {
+ return chain.proceed();
+ }
+ });
+ }
+ };
+
public void testPackageVisibility() {
Injector injector = Guice.createInjector(new PackageVisibilityTestModule());
injector.getInstance(PublicUserOfPackagePrivate.class); // This must pass.
@@ -80,9 +92,13 @@
static class TestVisibilityClassLoader
extends URLClassLoader {
- public TestVisibilityClassLoader() {
+ boolean hideInternals;
+
+ public TestVisibilityClassLoader(boolean hideInternals) {
super(new URL[0]);
+ this.hideInternals = hideInternals;
+
final String[] classpath = System.getProperty("java.class.path").split(File.pathSeparator);
for (final String element : classpath) {
try {
@@ -137,7 +153,10 @@
}
// hide internal non-test classes
- throw new ClassNotFoundException();
+ if (hideInternals) {
+ throw new ClassNotFoundException();
+ }
+ return super.loadClass(name, resolve);
}
}
@@ -150,7 +169,7 @@
protected void setUp() throws Exception {
super.setUp();
- ClassLoader testClassLoader = new TestVisibilityClassLoader();
+ ClassLoader testClassLoader = new TestVisibilityClassLoader(true);
proxyTestClass = (Class<ProxyTest>) testClassLoader.loadClass(ProxyTest.class.getName());
realClass = (Class<ProxyTestImpl>) testClassLoader.loadClass(ProxyTestImpl.class.getName());
@@ -268,4 +287,40 @@
return "HI";
}
}
+
+ static class Hidden {
+ }
+
+ public static class HiddenMethodReturn {
+ public Hidden method() {
+ return new Hidden();
+ }
+ }
+
+ public static class HiddenMethodParameter {
+ public void method(Hidden h) {
+ }
+ }
+
+ public void testClassLoaderBridging() throws Exception {
+ ClassLoader testClassLoader = new TestVisibilityClassLoader(false);
+
+ Class hiddenMethodReturnClass = testClassLoader.loadClass(HiddenMethodReturn.class.getName());
+ Class hiddenMethodParameterClass = testClassLoader.loadClass(HiddenMethodParameter.class.getName());
+
+ Injector injector = Guice.createInjector(noopInterceptorModule);
+
+ Class hiddenClass = testClassLoader.loadClass(Hidden.class.getName());
+ Constructor ctor = hiddenClass.getDeclaredConstructor();
+
+ ctor.setAccessible(true);
+
+ // don't use bridging for proxies with private parameters
+ Object o1 = injector.getInstance(hiddenMethodParameterClass);
+ o1.getClass().getDeclaredMethod("method", hiddenClass).invoke(o1, ctor.newInstance());
+
+ // don't use bridging for proxies with private return types
+ Object o2 = injector.getInstance(hiddenMethodReturnClass);
+ o2.getClass().getDeclaredMethod("method").invoke(o2);
+ }
}