You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by gn...@apache.org on 2020/07/08 19:26:32 UTC

[camel] branch master updated: [CAMEL-15278] Make sure the @Handler annotation is seen on proxied classes

This is an automated email from the ASF dual-hosted git repository.

gnodet pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/master by this push:
     new 3e1a63b  [CAMEL-15278] Make sure the @Handler annotation is seen on proxied classes
3e1a63b is described below

commit 3e1a63b5cf03faa97aff8255518a1814b821492e
Author: Guillaume Nodet <gn...@gmail.com>
AuthorDate: Wed Jul 8 14:37:54 2020 +0200

    [CAMEL-15278] Make sure the @Handler annotation is seen on proxied classes
---
 components/camel-bean/pom.xml                      |  12 +++
 .../org/apache/camel/component/bean/BeanInfo.java  |  16 ++++
 .../apache/camel/component/bean/BeanInfoTest.java  | 104 +++++++++++++++++++++
 3 files changed, 132 insertions(+)

diff --git a/components/camel-bean/pom.xml b/components/camel-bean/pom.xml
index 722ee82..6f0023f 100644
--- a/components/camel-bean/pom.xml
+++ b/components/camel-bean/pom.xml
@@ -40,5 +40,17 @@
             <version>${project.version}</version>
         </dependency>
 
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-junit-jupiter</artifactId>
+            <version>${mockito-version}</version>
+            <scope>test</scope>
+        </dependency>
+
     </dependencies>
 </project>
diff --git a/components/camel-bean/src/main/java/org/apache/camel/component/bean/BeanInfo.java b/components/camel-bean/src/main/java/org/apache/camel/component/bean/BeanInfo.java
index 16a3818..0491065 100644
--- a/components/camel-bean/src/main/java/org/apache/camel/component/bean/BeanInfo.java
+++ b/components/camel-bean/src/main/java/org/apache/camel/component/bean/BeanInfo.java
@@ -42,6 +42,7 @@ import org.apache.camel.Header;
 import org.apache.camel.Headers;
 import org.apache.camel.Message;
 import org.apache.camel.PropertyInject;
+import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.spi.Registry;
 import org.apache.camel.support.ObjectHelper;
 import org.apache.camel.support.builder.ExpressionBuilder;
@@ -93,6 +94,17 @@ public class BeanInfo {
     }
 
     public BeanInfo(CamelContext camelContext, Class<?> type, Method explicitMethod, ParameterMappingStrategy strategy) {
+        while (type.isSynthetic()) {
+            type = type.getSuperclass();
+            if (explicitMethod != null) {
+                try {
+                    explicitMethod = type.getDeclaredMethod(explicitMethod.getName(), explicitMethod.getParameterTypes());
+                } catch (NoSuchMethodException e) {
+                    throw new RuntimeCamelException("Unable to find a method " + explicitMethod + " on " + type, e);
+                }
+            }
+        }
+
         this.camelContext = camelContext;
         this.type = type;
         this.strategy = strategy;
@@ -405,6 +417,10 @@ public class BeanInfo {
         boolean hasCustomAnnotation = false;
         boolean hasHandlerAnnotation = org.apache.camel.util.ObjectHelper.hasAnnotation(method.getAnnotations(), Handler.class);
 
+        if (!hasHandlerAnnotation) {
+
+        }
+
         int size = parameterTypes.length;
         if (LOG.isTraceEnabled()) {
             LOG.trace("Creating MethodInfo for class: {} method: {} having {} parameters", clazz, method, size);
diff --git a/components/camel-bean/src/test/java/org/apache/camel/component/bean/BeanInfoTest.java b/components/camel-bean/src/test/java/org/apache/camel/component/bean/BeanInfoTest.java
new file mode 100644
index 0000000..7a12ca1
--- /dev/null
+++ b/components/camel-bean/src/test/java/org/apache/camel/component/bean/BeanInfoTest.java
@@ -0,0 +1,104 @@
+/*
+ * 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.camel.component.bean;
+
+import net.bytebuddy.ByteBuddy;
+import net.bytebuddy.description.modifier.Ownership;
+import net.bytebuddy.description.modifier.SyntheticState;
+import net.bytebuddy.description.modifier.Visibility;
+import net.bytebuddy.implementation.MethodDelegation;
+import net.bytebuddy.implementation.bind.annotation.RuntimeType;
+import org.apache.camel.CamelContext;
+import org.apache.camel.Handler;
+import org.apache.camel.spi.Registry;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import static net.bytebuddy.matcher.ElementMatchers.named;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.lenient;
+
+@ExtendWith(MockitoExtension.class)
+public class BeanInfoTest {
+
+    public static class MyClass {
+        @Handler
+        public void myMethod() {
+        }
+    }
+
+    public static class MyDerivedClass extends MyClass {
+        @Override
+        public void myMethod() {
+        }
+    }
+
+    @Mock
+    private CamelContext context;
+
+    @Mock
+    private Registry registry;
+
+    private BeanComponent beanComponent;
+
+    @BeforeEach
+    public void setup() {
+        beanComponent = new BeanComponent();
+        lenient().when(context.getComponent("bean", BeanComponent.class)).thenReturn(beanComponent);
+        lenient().when(context.getRegistry()).thenReturn(registry);
+        lenient().when(registry.lookupByNameAndType(BeanConstants.BEAN_PARAMETER_MAPPING_STRATEGY, ParameterMappingStrategy.class))
+                .thenReturn(null);
+    }
+
+    @Test
+    public void testHandlerClass() throws Exception {
+        BeanInfo info = new BeanInfo(context, MyClass.class.getMethod("myMethod"));
+        assertTrue(info.hasAnyMethodHandlerAnnotation());
+    }
+
+    @Test
+    public void testHandlerOnSyntheticProxy() throws Exception {
+        Object proxy = new ByteBuddy()
+                .subclass(MyClass.class)
+                .modifiers(SyntheticState.SYNTHETIC, Visibility.PUBLIC, Ownership.STATIC)
+                .method(named("myMethod"))
+                .intercept(MethodDelegation.to(
+                        new Object() {
+                            @RuntimeType
+                            public void intercept() throws Exception {
+                            }
+                        }))
+                .make()
+                .load(getClass().getClassLoader())
+                .getLoaded()
+                .getDeclaredConstructor()
+                .newInstance();
+        BeanInfo info = new BeanInfo(context, proxy.getClass().getMethod("myMethod"));
+        assertTrue(info.hasAnyMethodHandlerAnnotation());
+    }
+
+    @Test
+    public void testHandlerOnDerived() throws Exception {
+        BeanInfo info = new BeanInfo(context, MyDerivedClass.class.getMethod("myMethod"));
+        assertFalse(info.hasAnyMethodHandlerAnnotation());
+    }
+
+}