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
-~----------~----~----~----~------~----~------~--~---

Reply via email to