felix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From clem...@apache.org
Subject svn commit: r1758620 - in /felix/trunk/ipojo/runtime/core/src: main/java/org/apache/felix/ipojo/handlers/dependency/ test/java/org/apache/felix/ipojo/handlers/dependency/
Date Wed, 31 Aug 2016 15:25:22 GMT
Author: clement
Date: Wed Aug 31 15:25:22 2016
New Revision: 1758620

URL: http://svn.apache.org/viewvc?rev=1758620&view=rev
Log:
Apply the path for FELIX-5285.

Added:
    felix/trunk/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/handlers/dependency/NullableTest.java
    felix/trunk/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/handlers/dependency/TestSpecification.java
Modified:
    felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java

Modified: felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java?rev=1758620&r1=1758619&r2=1758620&view=diff
==============================================================================
--- felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java
(original)
+++ felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java
Wed Aug 31 15:25:22 2016
@@ -416,19 +416,19 @@ public class Dependency extends Dependen
         return new RuntimeException(message);
     }
 
-    private Object createNullableObject() {
+    private void createNullableObject() {
         // To load the proxy we use the POJO class loader. Indeed, this classloader imports
iPOJO (so can access to Nullable) and has
         // access to the service specification.
         if ( ! getSpecification().isInterface()) {
             getHandler().getLogger().log(Log.INFO, "Cannot create the nullable object for
" + getSpecification()
                     .getName() + " - the specification is not an interface");
-            return null;
+            return;
         }
 
         try {
             ClassLoader cl = new NullableClassLoader(
                     getHandler().getInstanceManager().getClazz().getClassLoader(),
-                    getSpecification().getClassLoader());
+                    findClassLoadersFromSpecification(getSpecification()));
 
             m_nullable =
                     Proxy.newProxyInstance(cl, new Class[]{
@@ -441,8 +441,28 @@ public class Dependency extends Dependen
         } catch (Throwable e) { // Catch any other exception that can occurs
             throw new IllegalStateException("Cannot create the Nullable object, an unexpected
error occurs", e);
         }
+    }
 
-        return m_nullable;
+    private List<ClassLoader> findClassLoadersFromSpecification(Class clazz) {
+        ArrayList<ClassLoader> classLoaders = new ArrayList<ClassLoader>();
+        ClassLoader specificationCL = clazz.getClassLoader();
+        classLoaders.add(specificationCL);
+        // use Class.getMethods() to go thru the full hierarchy of classes of the specification
+        for (Method method : clazz.getMethods()) {
+            for (Class<?> parameterType : method.getParameterTypes()) {
+                ClassLoader parameterCL = parameterType.getClassLoader();
+                if (parameterCL != null && !classLoaders.contains(parameterCL)) {
+                    classLoaders.add(parameterCL);
+                }
+            }
+            if (!Void.TYPE.equals(method.getReturnType())) {
+                ClassLoader returnCL = method.getReturnType().getClassLoader();
+                if (returnCL != null && !classLoaders.contains(returnCL)) {
+                    classLoaders.add(returnCL);
+                }
+            }
+        }
+        return classLoaders;
     }
 
     /**
@@ -1038,42 +1058,49 @@ public class Dependency extends Dependen
         /**
          * Component classloader.
          */
-        private ClassLoader m_component;
+        private ClassLoader       m_component;
         /**
-         * Specification classloader.
+         * Specification classloaders.
          */
-        private ClassLoader m_specification;
+        private List<ClassLoader> m_classLoadersFromSpecification;
 
         /**
          * Creates a NullableClassLoader.
-         *
-         * @param cmp  the component class loader.
-         * @param spec the specification class loader.
+         *  @param cmp  the component class loader.
+         * @param classLoadersFromSpecification the specification class loader plus the ones
referenced by parameters and return types.
          */
-        public NullableClassLoader(ClassLoader cmp, ClassLoader spec) {
+        public NullableClassLoader(ClassLoader cmp, List<ClassLoader> classLoadersFromSpecification)
{
             m_component = cmp;
-            m_specification = spec;
+            m_classLoadersFromSpecification = classLoadersFromSpecification;
         }
 
         /**
          * Loads the given class.
          * This method uses the classloader of the component class
-         * and (if not found) the specification classloader.
+         * and (if not found) the specification classloaders.
+         * Throws the last {@link ClassNotFoundException} caught while trying
+         * to load the class from the specifiation classloaders
          *
          * @param name the class name
          * @return the class object
-         * @throws ClassNotFoundException if the class is not found by the two classloaders.
+         * @throws ClassNotFoundException if the class is not found by the classloaders.
          * @see java.lang.ClassLoader#loadClass(java.lang.String)
          */
         public Class loadClass(String name) throws ClassNotFoundException {
             try {
                 return m_component.loadClass(name);
             } catch (ClassNotFoundException e) {
-                return m_specification.loadClass(name);
+                ClassNotFoundException lastCaught = null;
+                for (ClassLoader classLoader : m_classLoadersFromSpecification) {
+                    try {
+                        return classLoader.loadClass(name);
+                    } catch (ClassNotFoundException cnfe) {
+                        lastCaught = cnfe;
+                    }
+                }
+                throw lastCaught;
             }
         }
-
-
     }
 
     /**

Added: felix/trunk/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/handlers/dependency/NullableTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/handlers/dependency/NullableTest.java?rev=1758620&view=auto
==============================================================================
--- felix/trunk/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/handlers/dependency/NullableTest.java
(added)
+++ felix/trunk/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/handlers/dependency/NullableTest.java
Wed Aug 31 15:25:22 2016
@@ -0,0 +1,67 @@
+/*
+ * 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.felix.ipojo.handlers.dependency;
+
+import java.lang.reflect.Proxy;
+import org.apache.felix.ipojo.InstanceManager;
+import org.apache.felix.ipojo.Nullable;
+import org.apache.felix.ipojo.handlers.providedservice.ComponentTestWithSuperClass;
+import org.apache.felix.ipojo.test.MockBundle;
+import org.mockito.Mockito;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+public class NullableTest extends TestCase {
+
+    public void testOnGet_whenNullableEnabled_returnsAnInstanceOfNullableAndSpecification()
{
+        Bundle bundle = new MockBundle(Dependency.class.getClassLoader());
+        BundleContext context = Mockito.mock(BundleContext.class);
+        InstanceManager im = Mockito.mock(InstanceManager.class);
+        Mockito.when(im.getClazz()).thenReturn(ComponentTestWithSuperClass.class);
+        DependencyHandler handler = Mockito.mock(DependencyHandler.class);
+        Mockito.when(handler.getInstanceManager()).thenReturn(im);
+        Dependency dependency = new Dependency(handler, "a_field", TestSpecification.class,
null, true, false, true,
+                false, "dep", context, Dependency.DYNAMIC_BINDING_POLICY, null, null, null);
+        dependency.start();
+
+        Object service = dependency.onGet(null, null, null);
+
+        Assert.assertTrue(service instanceof Nullable);
+        Assert.assertTrue(service instanceof TestSpecification);
+    }
+
+    public void testOnGet_whenNullableEnabled_returnsAProxyWithNullableObjectAsInvocationHandler()
{
+        Bundle bundle = new MockBundle(Dependency.class.getClassLoader());
+        BundleContext context = Mockito.mock(BundleContext.class);
+        InstanceManager im = Mockito.mock(InstanceManager.class);
+        Mockito.when(im.getClazz()).thenReturn(ComponentTestWithSuperClass.class);
+        DependencyHandler handler = Mockito.mock(DependencyHandler.class);
+        Mockito.when(handler.getInstanceManager()).thenReturn(im);
+        Dependency dependency = new Dependency(handler, "a_field", TestSpecification.class,
null, true, false, true,
+            false, "dep", context, Dependency.DYNAMIC_BINDING_POLICY, null, null, null);
+        dependency.start();
+
+        Object service = dependency.onGet(null, null, null);
+
+        Assert.assertTrue(service instanceof Proxy);
+        Assert.assertTrue(Proxy.getInvocationHandler(service) instanceof NullableObject);
+    }
+}
\ No newline at end of file

Added: felix/trunk/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/handlers/dependency/TestSpecification.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/handlers/dependency/TestSpecification.java?rev=1758620&view=auto
==============================================================================
--- felix/trunk/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/handlers/dependency/TestSpecification.java
(added)
+++ felix/trunk/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/handlers/dependency/TestSpecification.java
Wed Aug 31 15:25:22 2016
@@ -0,0 +1,24 @@
+/*
+ * 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.felix.ipojo.handlers.dependency;
+
+public interface TestSpecification
+{
+    String doSomething(String param);
+}
\ No newline at end of file



Mime
View raw message