Author: limpbizkit
Date: Sat Nov 29 17:01:36 2008
New Revision: 710
Added:
trunk/test/com/googlecode/guice/PackageVisibilityTestModule.java
Removed:
trunk/test/com/googlecode/guice/PackageVisilibityTestModule.java
Modified:
trunk/src/com/google/inject/DefaultConstructionProxyFactory.java
trunk/src/com/google/inject/ProxyFactory.java
trunk/src/com/google/inject/SingleMethodInjector.java
trunk/src/com/google/inject/internal/BytecodeGen.java
trunk/test/com/googlecode/guice/BytecodeGenTest.java
Log:
Applied mcculls patch for issue 235 - OSGi classloading. The goal is to use
a bridge classloader whenever:
- the OSGi-invoked/extended methods are public
- the application classes are not loaded in a System classloader
This changes mccull's original patch by using the System Class Loader if
that was used to load the application classes. This should be a fairly
reasonable thing to do, and it means users who aren't using OSGi or Java EE
get a simpler experience.
Modified: trunk/src/com/google/inject/DefaultConstructionProxyFactory.java
==============================================================================
--- trunk/src/com/google/inject/DefaultConstructionProxyFactory.java
(original)
+++ trunk/src/com/google/inject/DefaultConstructionProxyFactory.java Sat
Nov 29 17:01:36 2008
@@ -62,7 +62,7 @@
return new ConstructionProxy<T>() {
Class<T> classToConstruct = constructor.getDeclaringClass();
- FastClass fastClass = newFastClass(classToConstruct,
Visibility.PUBLIC);
+ FastClass fastClass = newFastClass(classToConstruct,
Visibility.forMember(constructor));
final FastConstructor fastConstructor =
fastClass.getConstructor(constructor);
@SuppressWarnings("unchecked")
Modified: trunk/src/com/google/inject/ProxyFactory.java
==============================================================================
--- trunk/src/com/google/inject/ProxyFactory.java (original)
+++ trunk/src/com/google/inject/ProxyFactory.java Sat Nov 29 17:01:36 2008
@@ -94,7 +94,7 @@
indices.put(method, i);
}
- // true if all the methods we're intercepting are public. This impacts
which classloader we
+ // PUBLIC if all the methods we're intercepting are public. This
impacts which classloader we
// should use for loading the enhanced class
Visibility visibility = Visibility.PUBLIC;
@@ -154,7 +154,7 @@
final InjectionPoint injectionPoint) {
@SuppressWarnings("unchecked") // injection point's member must be a
Constructor<T>
final Constructor<T> standardConstructor = (Constructor<T>)
injectionPoint.getMember();
- FastClass fastClass = newFastClass(clazz, Visibility.PUBLIC);
+ FastClass fastClass = newFastClass(clazz,
Visibility.forMember(standardConstructor));
final FastConstructor fastConstructor
=
fastClass.getConstructor(standardConstructor.getParameterTypes());
Modified: trunk/src/com/google/inject/SingleMethodInjector.java
==============================================================================
--- trunk/src/com/google/inject/SingleMethodInjector.java (original)
+++ trunk/src/com/google/inject/SingleMethodInjector.java Sat Nov 29
17:01:36 2008
@@ -18,8 +18,8 @@
import com.google.common.collect.ImmutableList;
import com.google.inject.InjectorImpl.MethodInvoker;
-import com.google.inject.internal.BytecodeGen;
import com.google.inject.internal.BytecodeGen.Visibility;
+import static com.google.inject.internal.BytecodeGen.newFastClass;
import com.google.inject.internal.Errors;
import com.google.inject.internal.ErrorsException;
import com.google.inject.spi.InjectionPoint;
@@ -53,8 +53,7 @@
}
};
} else {
- FastClass fastClass = BytecodeGen.newFastClass(
- method.getDeclaringClass(), Visibility.forMember(method));
+ FastClass fastClass = newFastClass(method.getDeclaringClass(),
Visibility.forMember(method));
final FastMethod fastMethod = fastClass.getMethod(method);
methodInvoker = new MethodInvoker() {
@@ -92,4 +91,4 @@
errors.withSource(injectionPoint).errorInjectingMethod(cause);
}
}
-}
\ No newline at end of file
+}
Modified: trunk/src/com/google/inject/internal/BytecodeGen.java
==============================================================================
--- trunk/src/com/google/inject/internal/BytecodeGen.java (original)
+++ trunk/src/com/google/inject/internal/BytecodeGen.java Sat Nov 29
17:01:36 2008
@@ -17,7 +17,9 @@
package com.google.inject.internal;
import static com.google.inject.internal.ReferenceType.WEAK;
+import java.lang.reflect.Constructor;
import java.lang.reflect.Member;
+import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.security.AccessController;
import java.security.PrivilegedAction;
@@ -78,7 +80,7 @@
/** Use "-Dguice.custom.loader=false" to disable custom classloading. */
static final boolean HOOK_ENABLED
- = "true".equals(System.getProperty("guice.custom.loader", "false"));
+ = "true".equals(System.getProperty("guice.custom.loader", "true"));
/**
* Weak cache of bridge class loaders that make the Guice implementation
@@ -87,11 +89,6 @@
private static final ReferenceCache<ClassLoader, ClassLoader>
CLASS_LOADER_CACHE
= new ReferenceCache<ClassLoader, ClassLoader>(WEAK, WEAK) {
@Override protected ClassLoader create(final ClassLoader
typeClassLoader) {
- // Don't bother bridging existing bridge classloaders
- if (typeClassLoader instanceof BridgeClassLoader) {
- return typeClassLoader;
- }
-
logger.fine("Creating a bridge ClassLoader for " +
typeClassLoader);
return AccessController.doPrivileged(new
PrivilegedAction<ClassLoader>() {
public ClassLoader run() {
@@ -121,6 +118,16 @@
private static ClassLoader getClassLoader(Class<?> type, ClassLoader
delegate) {
delegate = canonicalize(delegate);
+ // if the application is running in the System classloader, assume we
can run there too
+ if (delegate == ClassLoader.getSystemClassLoader()) {
+ return delegate;
+ }
+
+ // Don't bother bridging existing bridge classloaders
+ if (delegate instanceof BridgeClassLoader) {
+ return delegate;
+ }
+
if (HOOK_ENABLED && Visibility.forType(type) == Visibility.PUBLIC) {
return CLASS_LOADER_CACHE.get(delegate);
}
@@ -184,9 +191,20 @@
};
public static Visibility forMember(Member member) {
- return (member.getModifiers() & (Modifier.PROTECTED |
Modifier.PUBLIC)) != 0
- ? PUBLIC
- : SAME_PACKAGE;
+ if ((member.getModifiers() & (Modifier.PROTECTED | Modifier.PUBLIC))
== 0) {
+ return SAME_PACKAGE;
+ }
+
+ Class[] parameterTypes = member instanceof Constructor
+ ? ((Constructor) member).getParameterTypes()
+ : ((Method) member).getParameterTypes();
+ for (Class<?> type : parameterTypes) {
+ if (forType(type) == SAME_PACKAGE) {
+ return SAME_PACKAGE;
+ }
+ }
+
+ return PUBLIC;
}
public static Visibility forType(Class<?> type) {
Modified: trunk/test/com/googlecode/guice/BytecodeGenTest.java
==============================================================================
--- trunk/test/com/googlecode/guice/BytecodeGenTest.java (original)
+++ trunk/test/com/googlecode/guice/BytecodeGenTest.java Sat Nov 29
17:01:36 2008
@@ -22,7 +22,7 @@
import com.google.inject.Injector;
import com.google.inject.Module;
import static com.google.inject.matcher.Matchers.any;
-import
com.googlecode.guice.PackageVisilibityTestModule.PublicUserOfPackagePrivate;
+import
com.googlecode.guice.PackageVisibilityTestModule.PublicUserOfPackagePrivate;
import java.io.File;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
@@ -54,7 +54,12 @@
};
public void testPackageVisibility() {
- Injector injector = Guice.createInjector(new
PackageVisilibityTestModule());
+ Injector injector = Guice.createInjector(new
PackageVisibilityTestModule());
+ injector.getInstance(PublicUserOfPackagePrivate.class); // This must
pass.
+ }
+
+ public void testInterceptedPackageVisibility() {
+ Injector injector = Guice.createInjector(interceptorModule, new
PackageVisibilityTestModule());
injector.getInstance(PublicUserOfPackagePrivate.class); // This must
pass.
}
@@ -176,20 +181,29 @@
assertEquals("HELLO WORLD", m.invoke(testObject));
}
- public void testProxyClassUnloading() {
+ public void testSystemClassLoaderIsUsedIfProxiedClassUsesIt() {
ProxyTest testProxy = Guice.createInjector(interceptorModule, new
Module() {
public void configure(Binder binder) {
binder.bind(ProxyTest.class).to(ProxyTestImpl.class);
}
}).getInstance(ProxyTest.class);
+ assertSame(testProxy.getClass().getClassLoader(),
ClassLoader.getSystemClassLoader());
+ }
+
+ public void testProxyClassUnloading() {
+ Object testObject = Guice.createInjector(interceptorModule, testModule)
+ .getInstance(proxyTestClass);
+ assertNotNull(testObject.getClass().getClassLoader());
+ assertNotSame(testObject.getClass().getClassLoader(),
ClassLoader.getSystemClassLoader());
+
// take a weak reference to the generated proxy class
- Reference<Class<?>> clazzRef = new
WeakReference<Class<?>>(testProxy.getClass());
+ Reference<Class<?>> clazzRef = new
WeakReference<Class<?>>(testObject.getClass());
assertNotNull(clazzRef.get());
// null the proxy
- testProxy = null;
+ testObject = null;
/*
* this should be enough to queue the weak reference
@@ -203,7 +217,7 @@
// If it fails, run the test again to make sure it's failing reliably.
assertNull(clazzRef.get());
}
-
+
public void testProxyingPackagePrivateMethods() {
Injector injector = Guice.createInjector(interceptorModule);
assertEquals("HI WORLD",
injector.getInstance(PackageClassPackageMethod.class).sayHi());
Added: trunk/test/com/googlecode/guice/PackageVisibilityTestModule.java
==============================================================================
--- (empty file)
+++ trunk/test/com/googlecode/guice/PackageVisibilityTestModule.java Sat
Nov 29 17:01:36 2008
@@ -0,0 +1,21 @@
+package com.googlecode.guice;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Inject;
+
+public class PackageVisibilityTestModule extends AbstractModule {
+
+ @Override
+ protected void configure() {
+ bind(PackagePrivateInterface.class).to(PackagePrivateImpl.class);
+ }
+
+ public static class PublicUserOfPackagePrivate {
+ @Inject public PublicUserOfPackagePrivate(PackagePrivateInterface ppi)
{}
+ @Inject public void
acceptPackagePrivateParameter(PackagePrivateInterface ppi) {}
+ }
+
+ interface PackagePrivateInterface {}
+
+ static class PackagePrivateImpl implements PackagePrivateInterface {}
+}
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"google-guice-dev" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/google-guice-dev?hl=en
-~----------~----~----~----~------~----~------~--~---