You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by nf...@apache.org on 2023/04/03 06:06:34 UTC
[camel-quarkus] branch main updated: Ref #4716: java-joor-dsl - Add RegisterForReflection support (#4726)
This is an automated email from the ASF dual-hosted git repository.
nfilotto pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git
The following commit(s) were added to refs/heads/main by this push:
new bdaf2fabcc Ref #4716: java-joor-dsl - Add RegisterForReflection support (#4726)
bdaf2fabcc is described below
commit bdaf2fabccb3ccda39fcbc4397b59280e520a2ea
Author: Nicolas Filotto <es...@users.noreply.github.com>
AuthorDate: Mon Apr 3 08:06:28 2023 +0200
Ref #4716: java-joor-dsl - Add RegisterForReflection support (#4726)
## Motivation
All the annotations added to a class managed by the extension `java-joor-dsl` are not considered by Quarkus since it is not part of the Jandex index.
This change aims to support the annotation `RegisterForReflection` to easily configure the reflection in Camel-K.
## Modifications:
* Produce the corresponding `ReflectiveClassBuildItem` and `LambdaCapturingTypeBuildItem` if a `RouteBuilder` is annotated with `RegisterForReflection`.
* Add some doc to explain the limitations
* Add a unit test to ensure that it works as expected
---
.../pages/reference/extensions/java-joor-dsl.adoc | 8 +++
.../java/joor/deployment/JavaJoorDslProcessor.java | 63 +++++++++++++++++++++-
.../runtime/src/main/doc/limitations.adoc | 3 ++
.../quarkus/dsl/java/joor/JavaJoorDslBean.java} | 20 ++++---
.../quarkus/dsl/java/joor/JavaJoorDslResource.java | 10 +++-
.../src/main/resources/routes/MyRoutes.java | 14 ++++-
.../quarkus/dsl/java/joor/JavaJoorDslTest.java | 12 ++++-
7 files changed, 119 insertions(+), 11 deletions(-)
diff --git a/docs/modules/ROOT/pages/reference/extensions/java-joor-dsl.adoc b/docs/modules/ROOT/pages/reference/extensions/java-joor-dsl.adoc
index 2461a370a6..edbf914728 100644
--- a/docs/modules/ROOT/pages/reference/extensions/java-joor-dsl.adoc
+++ b/docs/modules/ROOT/pages/reference/extensions/java-joor-dsl.adoc
@@ -43,3 +43,11 @@ Or add the coordinates to your existing project:
ifeval::[{doc-show-user-guide-link} == true]
Check the xref:user-guide/index.adoc[User guide] for more information about writing Camel Quarkus applications.
endif::[]
+
+[id="extensions-java-joor-dsl-camel-quarkus-limitations"]
+== Camel Quarkus limitations
+
+The annotations added to the classes to be compiled by the component are ignored by Quarkus. The only annotation that is
+partially supported by the extension is the annotation `RegisterForReflection` to ease the configuration of the reflection
+for the native mode however please note that the element `registerFullHierarchy` is not supported.
+
diff --git a/extensions/java-joor-dsl/deployment/src/main/java/org/apache/camel/quarkus/dsl/java/joor/deployment/JavaJoorDslProcessor.java b/extensions/java-joor-dsl/deployment/src/main/java/org/apache/camel/quarkus/dsl/java/joor/deployment/JavaJoorDslProcessor.java
index e556b46b99..fa42fe2a3c 100644
--- a/extensions/java-joor-dsl/deployment/src/main/java/org/apache/camel/quarkus/dsl/java/joor/deployment/JavaJoorDslProcessor.java
+++ b/extensions/java-joor-dsl/deployment/src/main/java/org/apache/camel/quarkus/dsl/java/joor/deployment/JavaJoorDslProcessor.java
@@ -31,12 +31,14 @@ import io.quarkus.deployment.annotations.ExecutionTime;
import io.quarkus.deployment.annotations.Record;
import io.quarkus.deployment.builditem.FeatureBuildItem;
import io.quarkus.deployment.builditem.GeneratedClassBuildItem;
+import io.quarkus.deployment.builditem.nativeimage.LambdaCapturingTypeBuildItem;
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem;
import io.quarkus.deployment.pkg.steps.NativeBuild;
import io.quarkus.maven.dependency.ResolvedDependency;
import io.quarkus.paths.PathCollection;
import io.quarkus.runtime.RuntimeValue;
+import io.quarkus.runtime.annotations.RegisterForReflection;
import org.apache.camel.CamelContext;
import org.apache.camel.dsl.java.joor.CompilationUnit;
import org.apache.camel.dsl.java.joor.Helper;
@@ -61,6 +63,8 @@ public class JavaJoorDslProcessor {
@BuildStep(onlyIf = NativeBuild.class)
void compileClassesAOT(BuildProducer<JavaJoorGeneratedClassBuildItem> generatedClass,
+ BuildProducer<ReflectiveClassBuildItem> reflectiveClass,
+ BuildProducer<LambdaCapturingTypeBuildItem> lambdaCapturingTypeProducer,
CurateOutcomeBuildItem curateOutcomeBuildItem) throws Exception {
Map<String, Resource> nameToResource = new HashMap<>();
LOG.debug("Loading .java resources");
@@ -96,6 +100,62 @@ public class JavaJoorDslProcessor {
generatedClass
.produce(new JavaJoorGeneratedClassBuildItem(className, nameToResource.get(className).getLocation(),
result.getByteCode(className)));
+ registerForReflection(reflectiveClass, lambdaCapturingTypeProducer,
+ result.getClass(className).getAnnotation(RegisterForReflection.class));
+ }
+ }
+
+ private void registerForReflection(BuildProducer<ReflectiveClassBuildItem> reflectiveClass,
+ BuildProducer<LambdaCapturingTypeBuildItem> lambdaCapturingTypeProducer,
+ RegisterForReflection annotation) {
+ if (annotation == null) {
+ return;
+ }
+
+ for (String lambdaCapturingType : annotation.lambdaCapturingTypes()) {
+ lambdaCapturingTypeProducer.produce(new LambdaCapturingTypeBuildItem(lambdaCapturingType));
+ }
+ boolean methods = annotation.methods();
+ boolean fields = annotation.fields();
+ boolean ignoreNested = annotation.ignoreNested();
+ boolean serialization = annotation.serialization();
+ boolean unsafeAllocated = annotation.unsafeAllocated();
+
+ if (annotation.registerFullHierarchy()) {
+ LOG.warn(
+ "The element 'registerFullHierarchy' of the annotation 'RegisterForReflection' is not supported by the extension Camel Java jOOR DSL");
+ }
+ for (Class<?> type : annotation.targets()) {
+ registerClass(type.getName(), methods, fields, ignoreNested, serialization,
+ unsafeAllocated, reflectiveClass);
+ }
+
+ for (String className : annotation.classNames()) {
+ registerClass(className, methods, fields, ignoreNested, serialization, unsafeAllocated,
+ reflectiveClass);
+ }
+ }
+
+ private void registerClass(String className, boolean methods, boolean fields, boolean ignoreNested, boolean serialization,
+ boolean unsafeAllocated, BuildProducer<ReflectiveClassBuildItem> reflectiveClass) {
+ reflectiveClass.produce(serialization
+ ? ReflectiveClassBuildItem.builder(className).serialization().unsafeAllocated(unsafeAllocated).build()
+ : ReflectiveClassBuildItem.builder(className).constructors().methods(methods).fields(fields)
+ .unsafeAllocated(unsafeAllocated).build());
+
+ if (ignoreNested) {
+ return;
+ }
+
+ try {
+ Class<?>[] declaredClasses = Thread.currentThread().getContextClassLoader().loadClass(className)
+ .getDeclaredClasses();
+ for (Class<?> clazz : declaredClasses) {
+ registerClass(clazz.getName(), methods, fields, false, serialization, unsafeAllocated,
+ reflectiveClass);
+ }
+ } catch (ClassNotFoundException e) {
+ LOG.warn("Failed to load Class {}", className, e);
}
}
@@ -106,8 +166,9 @@ public class JavaJoorDslProcessor {
for (JavaJoorGeneratedClassBuildItem clazz : classes) {
generatedClass.produce(new GeneratedClassBuildItem(true, clazz.getName(), clazz.getClassData()));
- reflectiveClass.produce(ReflectiveClassBuildItem.builder(clazz.getName()).build());
}
+ reflectiveClass.produce(ReflectiveClassBuildItem
+ .builder(classes.stream().map(JavaJoorGeneratedClassBuildItem::getName).toArray(String[]::new)).build());
}
@BuildStep(onlyIf = NativeBuild.class)
diff --git a/extensions/java-joor-dsl/runtime/src/main/doc/limitations.adoc b/extensions/java-joor-dsl/runtime/src/main/doc/limitations.adoc
new file mode 100644
index 0000000000..a818c7f8a9
--- /dev/null
+++ b/extensions/java-joor-dsl/runtime/src/main/doc/limitations.adoc
@@ -0,0 +1,3 @@
+The annotations added to the classes to be compiled by the component are ignored by Quarkus. The only annotation that is
+partially supported by the extension is the annotation `RegisterForReflection` to ease the configuration of the reflection
+for the native mode however please note that the element `registerFullHierarchy` is not supported.
\ No newline at end of file
diff --git a/integration-tests/java-joor-dsl/src/main/resources/routes/MyRoutes.java b/integration-tests/java-joor-dsl/src/main/java/org/apache/camel/quarkus/dsl/java/joor/JavaJoorDslBean.java
similarity index 70%
copy from integration-tests/java-joor-dsl/src/main/resources/routes/MyRoutes.java
copy to integration-tests/java-joor-dsl/src/main/java/org/apache/camel/quarkus/dsl/java/joor/JavaJoorDslBean.java
index 590dfe1d97..cea1834ff0 100644
--- a/integration-tests/java-joor-dsl/src/main/resources/routes/MyRoutes.java
+++ b/integration-tests/java-joor-dsl/src/main/java/org/apache/camel/quarkus/dsl/java/joor/JavaJoorDslBean.java
@@ -14,11 +14,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-public class MyRoutes extends org.apache.camel.builder.RouteBuilder {
- @Override
- public void configure() throws Exception {
- from("direct:joorHello")
- .id("my-java-route")
- .setBody(exchange -> "Hello " + exchange.getMessage().getBody() + " from jOOR!");
+package org.apache.camel.quarkus.dsl.java.joor;
+
+public class JavaJoorDslBean {
+
+ public static String hi(String name) {
+ return String.format("Hi %s", name);
}
-}
\ No newline at end of file
+
+ public static class Inner {
+ public static String addSource(String value) {
+ return String.format("%s from jOOR!", value);
+ }
+ }
+}
diff --git a/integration-tests/java-joor-dsl/src/main/java/org/apache/camel/quarkus/dsl/java/joor/JavaJoorDslResource.java b/integration-tests/java-joor-dsl/src/main/java/org/apache/camel/quarkus/dsl/java/joor/JavaJoorDslResource.java
index f1b3c1e596..797bd27b6f 100644
--- a/integration-tests/java-joor-dsl/src/main/java/org/apache/camel/quarkus/dsl/java/joor/JavaJoorDslResource.java
+++ b/integration-tests/java-joor-dsl/src/main/java/org/apache/camel/quarkus/dsl/java/joor/JavaJoorDslResource.java
@@ -75,8 +75,16 @@ public class JavaJoorDslResource {
@Path("/hello")
@Consumes(MediaType.TEXT_PLAIN)
@Produces(MediaType.TEXT_PLAIN)
- public String hello(String message) throws Exception {
+ public String hello(String message) {
return producerTemplate.requestBody("direct:joorHello", message, String.class);
}
+ @POST
+ @Path("/hi")
+ @Consumes(MediaType.TEXT_PLAIN)
+ @Produces(MediaType.TEXT_PLAIN)
+ public String hi(String name) {
+ return producerTemplate.requestBody("direct:joorHi", name, String.class);
+ }
+
}
diff --git a/integration-tests/java-joor-dsl/src/main/resources/routes/MyRoutes.java b/integration-tests/java-joor-dsl/src/main/resources/routes/MyRoutes.java
index 590dfe1d97..fdcfa82266 100644
--- a/integration-tests/java-joor-dsl/src/main/resources/routes/MyRoutes.java
+++ b/integration-tests/java-joor-dsl/src/main/resources/routes/MyRoutes.java
@@ -14,11 +14,23 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-public class MyRoutes extends org.apache.camel.builder.RouteBuilder {
+import io.quarkus.runtime.annotations.RegisterForReflection;
+import org.apache.camel.builder.RouteBuilder;
+
+@RegisterForReflection(classNames = "org.apache.camel.quarkus.dsl.java.joor.JavaJoorDslBean", ignoreNested = false)
+public class MyRoutes extends RouteBuilder {
@Override
public void configure() throws Exception {
from("direct:joorHello")
.id("my-java-route")
.setBody(exchange -> "Hello " + exchange.getMessage().getBody() + " from jOOR!");
+ from("direct:joorHi")
+ .id("reflection-route")
+ .process(exchange -> {
+ Class<?> c = Thread.currentThread().getContextClassLoader().loadClass("org.apache.camel.quarkus.dsl.java.joor.JavaJoorDslBean");
+ Object hi = c.getMethod("hi", String.class).invoke(null, exchange.getMessage().getBody());
+ Class<?> c2 = Thread.currentThread().getContextClassLoader().loadClass("org.apache.camel.quarkus.dsl.java.joor.JavaJoorDslBean$Inner");
+ exchange.getMessage().setBody(c2.getMethod("addSource", String.class).invoke(null, hi));
+ });
}
}
\ No newline at end of file
diff --git a/integration-tests/java-joor-dsl/src/test/java/org/apache/camel/quarkus/dsl/java/joor/JavaJoorDslTest.java b/integration-tests/java-joor-dsl/src/test/java/org/apache/camel/quarkus/dsl/java/joor/JavaJoorDslTest.java
index 3fbf057b98..56862ea213 100644
--- a/integration-tests/java-joor-dsl/src/test/java/org/apache/camel/quarkus/dsl/java/joor/JavaJoorDslTest.java
+++ b/integration-tests/java-joor-dsl/src/test/java/org/apache/camel/quarkus/dsl/java/joor/JavaJoorDslTest.java
@@ -35,6 +35,16 @@ class JavaJoorDslTest {
.body(CoreMatchers.is("Hello Camelus bactrianus from jOOR!"));
}
+ @Test
+ void joorHi() {
+ RestAssured.given()
+ .body("Will Smith")
+ .post("/java-joor-dsl/hi")
+ .then()
+ .statusCode(200)
+ .body(CoreMatchers.is("Hi Will Smith from jOOR!"));
+ }
+
@Test
void testMainInstanceWithJavaRoutes() {
RestAssured.given()
@@ -53,6 +63,6 @@ class JavaJoorDslTest {
.get("/java-joor-dsl/main/routes")
.then()
.statusCode(200)
- .body(CoreMatchers.is("my-java-route"));
+ .body(CoreMatchers.is("my-java-route,reflection-route"));
}
}