You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2022/04/26 16:21:04 UTC
[camel] branch main updated (c222cee10e9 -> 693ecd9d23d)
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a change to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
from c222cee10e9 CAMEL-17864: Fix the scope of the deps of the camel-bundle-plugin (#7496)
new 1ea1872bdd6 CAMEL-18014: camel-java-dsl - Allow to capture compiled byte code
new 6e0b7d459fa Typo
new bd73e37db82 CAMEL-18014: camel-java-dsl - Allow to capture compiled byte code
new 693ecd9d23d CAMEL-18014: camel-java-dsl - Allow to capture compiled byte code
The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
.../camel/dsl/support/CompilePostProcessor.java | 3 +-
dsl/camel-fatjar-main/pom.xml | 2 +-
.../services/org/apache/camel/other.properties | 2 +-
.../services/org/apache/camel/routes-loader/class | 2 +
.../camel/dsl/java/joor/ByteArrayClassLoader.java | 43 ++++++++
.../dsl/java/joor/ClassRoutesBuilderLoader.java | 91 ++++++++++++++++
.../camel/dsl/java/joor/CompilationUnit.java | 14 ++-
.../dsl/java/joor/JavaRoutesBuilderLoader.java | 3 +-
.../apache/camel/dsl/java/joor/MultiCompile.java | 47 ++++-----
.../java/joor/ClassRoutesBuilderLoaderTest.java | 69 +++++++++++++
.../org/apache/camel/dsl/java/joor/DummyRoute.java | 28 +++++
.../dsl/java/joor/JavaJoorCaptureByteCodeTest.java | 114 +++++++++++++++++++++
.../src/test/resources/routes/MyMockRoute.java | 25 +++++
.../src/main/resources/templates/manifest.tmpl | 2 +-
.../camel/main/AnnotationDependencyInjection.java | 8 +-
15 files changed, 416 insertions(+), 37 deletions(-)
create mode 100644 dsl/camel-java-joor-dsl/src/generated/resources/META-INF/services/org/apache/camel/routes-loader/class
create mode 100644 dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/ByteArrayClassLoader.java
create mode 100644 dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/ClassRoutesBuilderLoader.java
create mode 100644 dsl/camel-java-joor-dsl/src/test/java/org/apache/camel/dsl/java/joor/ClassRoutesBuilderLoaderTest.java
create mode 100644 dsl/camel-java-joor-dsl/src/test/java/org/apache/camel/dsl/java/joor/DummyRoute.java
create mode 100644 dsl/camel-java-joor-dsl/src/test/java/org/apache/camel/dsl/java/joor/JavaJoorCaptureByteCodeTest.java
create mode 100644 dsl/camel-java-joor-dsl/src/test/resources/routes/MyMockRoute.java
[camel] 03/04: CAMEL-18014: camel-java-dsl - Allow to capture compiled byte code
Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
commit bd73e37db82f034d946a5e726cf8d7f3c0c2829a
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Tue Apr 26 18:18:28 2022 +0200
CAMEL-18014: camel-java-dsl - Allow to capture compiled byte code
---
.../dsl/java/joor/ClassRoutesBuilderLoader.java | 40 ++++++--
.../apache/camel/dsl/java/joor/MultiCompile.java | 5 +-
.../java/joor/ClassRoutesBuilderLoaderTest.java | 11 +-
.../dsl/java/joor/JavaJoorCaptureByteCodeTest.java | 114 +++++++++++++++++++++
.../src/test/resources/routes/MyMockRoute.java | 25 +++++
5 files changed, 177 insertions(+), 18 deletions(-)
diff --git a/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/ClassRoutesBuilderLoader.java b/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/ClassRoutesBuilderLoader.java
index 541b5a05632..b94a690026c 100644
--- a/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/ClassRoutesBuilderLoader.java
+++ b/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/ClassRoutesBuilderLoader.java
@@ -1,5 +1,11 @@
package org.apache.camel.dsl.java.joor;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
import org.apache.camel.CamelContextAware;
import org.apache.camel.RoutesBuilder;
import org.apache.camel.api.management.ManagedResource;
@@ -12,10 +18,6 @@ import org.apache.camel.spi.annotations.RoutesLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Collection;
-
@ManagedResource(description = "Managed ClassRoutesBuilderLoader")
@RoutesLoader(ClassRoutesBuilderLoader.EXTENSION)
public class ClassRoutesBuilderLoader extends ExtendedRouteBuilderLoaderSupport {
@@ -32,13 +34,23 @@ public class ClassRoutesBuilderLoader extends ExtendedRouteBuilderLoaderSupport
protected Collection<RoutesBuilder> doLoadRoutesBuilders(Collection<Resource> resources) throws Exception {
Collection<RoutesBuilder> answer = new ArrayList<>();
+ // load all the byte code first from the resources
+ Map<String, byte[]> byteCodes = new LinkedHashMap<>();
for (Resource res : resources) {
- String className = res.getLocation();
- className = className.replace('/', '.');
- if (className.endsWith(".class")) {
- className = className.substring(0, className.length() - 6);
+ String className = asClassName(res);
+ InputStream is = res.getInputStream();
+ if (is != null) {
+ byte[] code = is.readAllBytes();
+ byteCodes.put(className, code);
}
- Class<?> clazz = getCamelContext().getClassResolver().resolveMandatoryClass(className);
+ }
+
+ MultiCompile.ByteArrayClassLoader cl = new MultiCompile.ByteArrayClassLoader(byteCodes);
+
+ // instantiate classes from the byte codes
+ for (Resource res : resources) {
+ String className = asClassName(res);
+ Class<?> clazz = cl.findClass(className);
Object obj;
try {
@@ -63,9 +75,17 @@ public class ClassRoutesBuilderLoader extends ExtendedRouteBuilderLoaderSupport
RouteBuilder builder = (RouteBuilder) obj;
answer.add(builder);
}
-
}
return answer;
}
+
+ private static String asClassName(Resource resource) {
+ String className = resource.getLocation();
+ className = className.replace('/', '.');
+ if (className.endsWith(".class")) {
+ className = className.substring(0, className.length() - 6);
+ }
+ return className;
+ }
}
diff --git a/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/MultiCompile.java b/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/MultiCompile.java
index 20ac864c381..3f59f0b6bbf 100644
--- a/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/MultiCompile.java
+++ b/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/MultiCompile.java
@@ -35,7 +35,6 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
-import java.util.concurrent.atomic.AtomicReference;
import javax.tools.FileObject;
import javax.tools.ForwardingJavaFileManager;
@@ -65,8 +64,8 @@ public final class MultiCompile {
/**
* Compiles multiple files as one unit
*
- * @param unit the files to compile in the same unit
- * @return the compilation result
+ * @param unit the files to compile in the same unit
+ * @return the compilation result
*/
public static CompilationUnit.Result compileUnit(CompilationUnit unit) {
CompilationUnit.Result result = CompilationUnit.result();
diff --git a/dsl/camel-java-joor-dsl/src/test/java/org/apache/camel/dsl/java/joor/ClassRoutesBuilderLoaderTest.java b/dsl/camel-java-joor-dsl/src/test/java/org/apache/camel/dsl/java/joor/ClassRoutesBuilderLoaderTest.java
index 0df7230a139..c0d9cfbbe4a 100644
--- a/dsl/camel-java-joor-dsl/src/test/java/org/apache/camel/dsl/java/joor/ClassRoutesBuilderLoaderTest.java
+++ b/dsl/camel-java-joor-dsl/src/test/java/org/apache/camel/dsl/java/joor/ClassRoutesBuilderLoaderTest.java
@@ -16,6 +16,10 @@
*/
package org.apache.camel.dsl.java.joor;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collection;
+
import org.apache.camel.RoutesBuilder;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.impl.DefaultCamelContext;
@@ -25,10 +29,6 @@ import org.apache.camel.support.ResourceSupport;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Collection;
-
import static org.assertj.core.api.Assertions.assertThat;
public class ClassRoutesBuilderLoaderTest {
@@ -44,7 +44,8 @@ public class ClassRoutesBuilderLoaderTest {
@Override
public InputStream getInputStream() throws IOException {
- return null;
+ return ClassRoutesBuilderLoaderTest.class
+ .getResourceAsStream("/org/apache/camel/dsl/java/joor/DummyRoute.class");
}
};
Collection<RoutesBuilder> builders = context.getRoutesLoader().findRoutesBuilders(resource);
diff --git a/dsl/camel-java-joor-dsl/src/test/java/org/apache/camel/dsl/java/joor/JavaJoorCaptureByteCodeTest.java b/dsl/camel-java-joor-dsl/src/test/java/org/apache/camel/dsl/java/joor/JavaJoorCaptureByteCodeTest.java
new file mode 100644
index 00000000000..12c91100328
--- /dev/null
+++ b/dsl/camel-java-joor-dsl/src/test/java/org/apache/camel/dsl/java/joor/JavaJoorCaptureByteCodeTest.java
@@ -0,0 +1,114 @@
+/*
+ * 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.dsl.java.joor;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collection;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.dsl.support.CompilePostProcessor;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.spi.Resource;
+import org.apache.camel.support.ResourceSupport;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+public class JavaJoorCaptureByteCodeTest {
+
+ private final MyPostCompiler postCompiler = new MyPostCompiler();
+
+ @Test
+ public void testCaptureByteCode() throws Exception {
+ try (DefaultCamelContext context = new DefaultCamelContext()) {
+ context.getRegistry().bind("MyPostCompiler", postCompiler);
+ context.start();
+
+ Resource resource = context.getResourceLoader().resolveResource("/routes/MyMockRoute.java");
+ Collection<RoutesBuilder> builders = context.getRoutesLoader().findRoutesBuilders(resource);
+
+ assertThat(builders).hasSize(1);
+
+ RouteBuilder builder = (RouteBuilder) builders.iterator().next();
+ builder.setCamelContext(context);
+ builder.configure();
+
+ assertEquals("MyMockRoute", postCompiler.getName());
+ assertNotNull(postCompiler.getCode());
+ }
+
+ // load the route (its byte code) from another context
+
+ try (DefaultCamelContext context = new DefaultCamelContext()) {
+ context.start();
+
+ Resource res = new ResourceSupport("class", "MyMockRoute.class") {
+ @Override
+ public boolean exists() {
+ return true;
+ }
+
+ @Override
+ public InputStream getInputStream() throws IOException {
+ return new ByteArrayInputStream(postCompiler.getCode());
+ }
+ };
+
+ Collection<RoutesBuilder> builders = context.getRoutesLoader().findRoutesBuilders(res);
+ assertThat(builders).hasSize(1);
+
+ RouteBuilder builder = (RouteBuilder) builders.iterator().next();
+ builder.setCamelContext(context);
+ context.addRoutes(builder);
+
+ MockEndpoint mock = context.getEndpoint("mock:result", MockEndpoint.class);
+ mock.expectedBodiesReceived("Hello ByteCode");
+ ProducerTemplate template = context.createProducerTemplate();
+ template.sendBody("direct:start", "Hello ByteCode");
+ mock.assertIsSatisfied();
+ }
+ }
+
+ private static final class MyPostCompiler implements CompilePostProcessor {
+
+ private String name;
+ private byte[] code;
+
+ @Override
+ public void postCompile(CamelContext camelContext, String name, Class<?> clazz, byte[] byteCode, Object instance)
+ throws Exception {
+ this.name = name;
+ this.code = byteCode;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public byte[] getCode() {
+ return code;
+ }
+ }
+}
diff --git a/dsl/camel-java-joor-dsl/src/test/resources/routes/MyMockRoute.java b/dsl/camel-java-joor-dsl/src/test/resources/routes/MyMockRoute.java
new file mode 100644
index 00000000000..f211004504a
--- /dev/null
+++ b/dsl/camel-java-joor-dsl/src/test/resources/routes/MyMockRoute.java
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+import org.apache.camel.builder.RouteBuilder;
+
+public class MyMockRoute extends RouteBuilder {
+ @Override
+ public void configure() throws Exception {
+ from("direct:start")
+ .to("mock:result");
+ }
+}
\ No newline at end of file
[camel] 01/04: CAMEL-18014: camel-java-dsl - Allow to capture compiled byte code
Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
commit 1ea1872bdd68c78bfec1dbdd670492fa437ab9db
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Tue Apr 26 16:04:34 2022 +0200
CAMEL-18014: camel-java-dsl - Allow to capture compiled byte code
---
.../camel/dsl/support/CompilePostProcessor.java | 3 +-
.../services/org/apache/camel/routes-loader/class | 2 +
.../dsl/java/joor/ClassRoutesBuilderLoader.java | 71 ++++++++++++++++++++++
.../camel/dsl/java/joor/CompilationUnit.java | 14 ++++-
.../dsl/java/joor/JavaRoutesBuilderLoader.java | 3 +-
.../apache/camel/dsl/java/joor/MultiCompile.java | 30 ++++++---
.../java/joor/ClassRoutesBuilderLoaderTest.java | 68 +++++++++++++++++++++
.../org/apache/camel/dsl/java/joor/DummyRoute.java | 28 +++++++++
.../camel/main/AnnotationDependencyInjection.java | 8 +--
9 files changed, 213 insertions(+), 14 deletions(-)
diff --git a/dsl/camel-dsl-support/src/main/java/org/apache/camel/dsl/support/CompilePostProcessor.java b/dsl/camel-dsl-support/src/main/java/org/apache/camel/dsl/support/CompilePostProcessor.java
index 021a97fc0ce..16d6d960522 100644
--- a/dsl/camel-dsl-support/src/main/java/org/apache/camel/dsl/support/CompilePostProcessor.java
+++ b/dsl/camel-dsl-support/src/main/java/org/apache/camel/dsl/support/CompilePostProcessor.java
@@ -33,12 +33,13 @@ public interface CompilePostProcessor {
* @param camelContext the camel context
* @param name the name of the resource/class
* @param clazz the class
+ * @param byteCode byte code that was compiled from the source as the class (only supported on some DSLs)
* @param instance the object created as instance of the class (if any)
* @throws Exception is thrown if error during post-processing
*/
void postCompile(
CamelContext camelContext, String name,
- Class<?> clazz, Object instance)
+ Class<?> clazz, byte[] byteCode, Object instance)
throws Exception;
}
diff --git a/dsl/camel-java-joor-dsl/src/generated/resources/META-INF/services/org/apache/camel/routes-loader/class b/dsl/camel-java-joor-dsl/src/generated/resources/META-INF/services/org/apache/camel/routes-loader/class
new file mode 100644
index 00000000000..07e045d7a62
--- /dev/null
+++ b/dsl/camel-java-joor-dsl/src/generated/resources/META-INF/services/org/apache/camel/routes-loader/class
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.dsl.java.joor.ClassRoutesBuilderLoader
diff --git a/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/ClassRoutesBuilderLoader.java b/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/ClassRoutesBuilderLoader.java
new file mode 100644
index 00000000000..541b5a05632
--- /dev/null
+++ b/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/ClassRoutesBuilderLoader.java
@@ -0,0 +1,71 @@
+package org.apache.camel.dsl.java.joor;
+
+import org.apache.camel.CamelContextAware;
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.api.management.ManagedResource;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.dsl.support.CompilePostProcessor;
+import org.apache.camel.dsl.support.ExtendedRouteBuilderLoaderSupport;
+import org.apache.camel.spi.Resource;
+import org.apache.camel.spi.ResourceAware;
+import org.apache.camel.spi.annotations.RoutesLoader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+
+@ManagedResource(description = "Managed ClassRoutesBuilderLoader")
+@RoutesLoader(ClassRoutesBuilderLoader.EXTENSION)
+public class ClassRoutesBuilderLoader extends ExtendedRouteBuilderLoaderSupport {
+
+ public static final String EXTENSION = "class";
+
+ private static final Logger LOG = LoggerFactory.getLogger(ClassRoutesBuilderLoader.class);
+
+ public ClassRoutesBuilderLoader() {
+ super(EXTENSION);
+ }
+
+ @Override
+ protected Collection<RoutesBuilder> doLoadRoutesBuilders(Collection<Resource> resources) throws Exception {
+ Collection<RoutesBuilder> answer = new ArrayList<>();
+
+ for (Resource res : resources) {
+ String className = res.getLocation();
+ className = className.replace('/', '.');
+ if (className.endsWith(".class")) {
+ className = className.substring(0, className.length() - 6);
+ }
+ Class<?> clazz = getCamelContext().getClassResolver().resolveMandatoryClass(className);
+
+ Object obj;
+ try {
+ // requires a default no-arg constructor otherwise we skip the class
+ obj = getCamelContext().getInjector().newInstance(clazz);
+ } catch (Exception e) {
+ LOG.debug("Loaded class: " + className + " must have a default no-arg constructor. Skipping.");
+ continue;
+ }
+
+ // inject context and resource
+ CamelContextAware.trySetCamelContext(obj, getCamelContext());
+ ResourceAware.trySetResource(obj, res);
+
+ // support custom annotation scanning post compilation
+ // such as to register custom beans, type converters, etc.
+ for (CompilePostProcessor pre : getCompilePostProcessors()) {
+ pre.postCompile(getCamelContext(), className, clazz, null, obj);
+ }
+
+ if (obj instanceof RouteBuilder) {
+ RouteBuilder builder = (RouteBuilder) obj;
+ answer.add(builder);
+ }
+
+ }
+
+ return answer;
+ }
+}
diff --git a/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/CompilationUnit.java b/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/CompilationUnit.java
index 2f0dfcc1f85..e6b489ad029 100644
--- a/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/CompilationUnit.java
+++ b/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/CompilationUnit.java
@@ -33,9 +33,11 @@ public class CompilationUnit {
*/
public static class Result {
private final Map<String, Class<?>> classes = new LinkedHashMap<>();
+ private final Map<String, byte[]> compiled = new LinkedHashMap<>();
- void addResult(String className, Class<?> clazz) {
+ void addResult(String className, Class<?> clazz, byte[] byteCode) {
classes.put(className, clazz);
+ compiled.put(className, byteCode);
}
/**
@@ -48,6 +50,16 @@ public class CompilationUnit {
return classes.get(className);
}
+ /**
+ * Gets the compiled byte code by its class name
+ *
+ * @param className the class name
+ * @return the compiled byte code
+ */
+ public byte[] getByteCode(String className) {
+ return compiled.get(className);
+ }
+
/**
* Number of classes in the result
*/
diff --git a/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/JavaRoutesBuilderLoader.java b/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/JavaRoutesBuilderLoader.java
index 429d57c7156..9e87733f52a 100644
--- a/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/JavaRoutesBuilderLoader.java
+++ b/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/JavaRoutesBuilderLoader.java
@@ -103,7 +103,8 @@ public class JavaRoutesBuilderLoader extends ExtendedRouteBuilderLoaderSupport {
// support custom annotation scanning post compilation
// such as to register custom beans, type converters, etc.
for (CompilePostProcessor pre : getCompilePostProcessors()) {
- pre.postCompile(getCamelContext(), className, clazz, obj);
+ byte[] byteCode = result.getByteCode(className);
+ pre.postCompile(getCamelContext(), className, clazz, byteCode, obj);
}
if (obj instanceof RouteBuilder) {
diff --git a/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/MultiCompile.java b/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/MultiCompile.java
index dccad22136d..20ac864c381 100644
--- a/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/MultiCompile.java
+++ b/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/MultiCompile.java
@@ -30,10 +30,12 @@ import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Deque;
+import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.concurrent.atomic.AtomicReference;
import javax.tools.FileObject;
import javax.tools.ForwardingJavaFileManager;
@@ -63,8 +65,8 @@ public final class MultiCompile {
/**
* Compiles multiple files as one unit
*
- * @param unit the files to compile in the same unit
- * @return the compilation result
+ * @param unit the files to compile in the same unit
+ * @return the compilation result
*/
public static CompilationUnit.Result compileUnit(CompilationUnit unit) {
CompilationUnit.Result result = CompilationUnit.result();
@@ -77,7 +79,7 @@ public final class MultiCompile {
unit.getInput().forEach((cn, code) -> {
try {
Class<?> clazz = cl.loadClass(cn);
- result.addResult(cn, clazz);
+ result.addResult(cn, clazz, null);
} catch (ClassNotFoundException ignore) {
files.add(new CharSequenceJavaFileObject(cn, code));
}
@@ -147,19 +149,33 @@ public final class MultiCompile {
// The heuristic will work only with classes that follow standard naming conventions.
// A better implementation is difficult at this point.
Lookup privateLookup = MethodHandles.privateLookupIn(caller, lookup);
+ final Map<String, byte[]> byteCodes = new HashMap<>();
Class<?> clazz = fileManager.loadAndReturnMainClass(className,
- (name, bytes) -> privateLookup.defineClass(bytes));
+ (name, bytes) -> {
+ Class<?> loaded = privateLookup.defineClass(bytes);
+ if (loaded != null) {
+ byteCodes.put(name, bytes);
+ }
+ return loaded;
+ });
if (clazz != null) {
- result.addResult(className, clazz);
+ result.addResult(className, clazz, byteCodes.get(className));
}
} else {
// Otherwise, use an arbitrary class loader. This approach doesn't allow for
// loading private-access interfaces in the compiled class's type hierarchy
ByteArrayClassLoader c = new ByteArrayClassLoader(fileManager.classes());
+ final Map<String, byte[]> byteCodes = new HashMap<>();
Class<?> clazz = fileManager.loadAndReturnMainClass(className,
- (name, bytes) -> c.loadClass(name));
+ (name, bytes) -> {
+ Class<?> loaded = c.loadClass(name);
+ if (loaded != null) {
+ byteCodes.put(name, bytes);
+ }
+ return loaded;
+ });
if (clazz != null) {
- result.addResult(className, clazz);
+ result.addResult(className, clazz, byteCodes.get(className));
}
}
}
diff --git a/dsl/camel-java-joor-dsl/src/test/java/org/apache/camel/dsl/java/joor/ClassRoutesBuilderLoaderTest.java b/dsl/camel-java-joor-dsl/src/test/java/org/apache/camel/dsl/java/joor/ClassRoutesBuilderLoaderTest.java
new file mode 100644
index 00000000000..0df7230a139
--- /dev/null
+++ b/dsl/camel-java-joor-dsl/src/test/java/org/apache/camel/dsl/java/joor/ClassRoutesBuilderLoaderTest.java
@@ -0,0 +1,68 @@
+/*
+ * 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.dsl.java.joor;
+
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.model.ToDefinition;
+import org.apache.camel.spi.Resource;
+import org.apache.camel.support.ResourceSupport;
+import org.assertj.core.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collection;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class ClassRoutesBuilderLoaderTest {
+
+ @Test
+ void testLoadRoutes() throws Exception {
+ try (DefaultCamelContext context = new DefaultCamelContext()) {
+ Resource resource = new ResourceSupport("class", "org/apache/camel/dsl/java/joor/DummyRoute.class") {
+ @Override
+ public boolean exists() {
+ return true;
+ }
+
+ @Override
+ public InputStream getInputStream() throws IOException {
+ return null;
+ }
+ };
+ Collection<RoutesBuilder> builders = context.getRoutesLoader().findRoutesBuilders(resource);
+
+ assertThat(builders).hasSize(1);
+
+ RouteBuilder builder = (RouteBuilder) builders.iterator().next();
+ builder.setCamelContext(context);
+ builder.configure();
+
+ Assertions.assertThat(builder.getRouteCollection().getRoutes())
+ .hasSize(1)
+ .first()
+ .satisfies(rd -> {
+ Assertions.assertThat(rd.getInput().getEndpointUri()).matches("direct:dummy");
+ Assertions.assertThat(rd.getOutputs().get(0)).isInstanceOf(ToDefinition.class);
+ });
+ }
+ }
+
+}
diff --git a/dsl/camel-java-joor-dsl/src/test/java/org/apache/camel/dsl/java/joor/DummyRoute.java b/dsl/camel-java-joor-dsl/src/test/java/org/apache/camel/dsl/java/joor/DummyRoute.java
new file mode 100644
index 00000000000..eda67fb303a
--- /dev/null
+++ b/dsl/camel-java-joor-dsl/src/test/java/org/apache/camel/dsl/java/joor/DummyRoute.java
@@ -0,0 +1,28 @@
+/*
+ * 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.dsl.java.joor;
+
+import org.apache.camel.builder.RouteBuilder;
+
+public class DummyRoute extends RouteBuilder {
+
+ @Override
+ public void configure() throws Exception {
+ from("direct:dummy")
+ .to("mock:end");
+ }
+}
diff --git a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/AnnotationDependencyInjection.java b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/AnnotationDependencyInjection.java
index 6689408cca3..5c3d4a40199 100644
--- a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/AnnotationDependencyInjection.java
+++ b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/AnnotationDependencyInjection.java
@@ -77,7 +77,7 @@ public final class AnnotationDependencyInjection {
private static class TypeConverterCompilePostProcessor implements CompilePostProcessor {
@Override
- public void postCompile(CamelContext camelContext, String name, Class<?> clazz, Object instance) throws Exception {
+ public void postCompile(CamelContext camelContext, String name, Class<?> clazz, byte[] byteCode, Object instance) throws Exception {
if (clazz.isAnnotationPresent(Converter.class)) {
TypeConverterRegistry tcr = camelContext.getTypeConverterRegistry();
TypeConverterExists exists = tcr.getTypeConverterExists();
@@ -99,7 +99,7 @@ public final class AnnotationDependencyInjection {
private static class BindToRegistryCompilePostProcessor implements CompilePostProcessor {
@Override
- public void postCompile(CamelContext camelContext, String name, Class<?> clazz, Object instance) throws Exception {
+ public void postCompile(CamelContext camelContext, String name, Class<?> clazz, byte[] byteCode, Object instance) throws Exception {
BindToRegistry bir = instance.getClass().getAnnotation(BindToRegistry.class);
Configuration cfg = instance.getClass().getAnnotation(Configuration.class);
if (bir != null || cfg != null || instance instanceof CamelConfiguration) {
@@ -130,7 +130,7 @@ public final class AnnotationDependencyInjection {
private static class SpringAnnotationCompilePostProcessor implements CompilePostProcessor {
@Override
- public void postCompile(CamelContext camelContext, String name, Class<?> clazz, Object instance) throws Exception {
+ public void postCompile(CamelContext camelContext, String name, Class<?> clazz, byte[] byteCode, Object instance) throws Exception {
// @Component and @Service are the same
Component comp = clazz.getAnnotation(Component.class);
Service service = clazz.getAnnotation(Service.class);
@@ -202,7 +202,7 @@ public final class AnnotationDependencyInjection {
private static class QuarkusAnnotationCompilePostProcessor implements CompilePostProcessor {
@Override
- public void postCompile(CamelContext camelContext, String name, Class<?> clazz, Object instance) throws Exception {
+ public void postCompile(CamelContext camelContext, String name, Class<?> clazz, byte[] byteCode, Object instance) throws Exception {
// @ApplicationScoped and @Singleton are considered the same
ApplicationScoped as = clazz.getAnnotation(ApplicationScoped.class);
Singleton ss = clazz.getAnnotation(Singleton.class);
[camel] 02/04: Typo
Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
commit 6e0b7d459fa13a796c114a59068566360f2f541b
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Tue Apr 26 16:05:18 2022 +0200
Typo
---
dsl/camel-fatjar-main/pom.xml | 2 +-
.../resources/META-INF/services/org/apache/camel/other.properties | 2 +-
.../camel-jbang-core/src/main/resources/templates/manifest.tmpl | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/dsl/camel-fatjar-main/pom.xml b/dsl/camel-fatjar-main/pom.xml
index ee50ce4e293..e29790698f7 100644
--- a/dsl/camel-fatjar-main/pom.xml
+++ b/dsl/camel-fatjar-main/pom.xml
@@ -30,7 +30,7 @@
<artifactId>camel-fatjar-main</artifactId>
<packaging>jar</packaging>
- <name>Camel :: Far-JAR Main</name>
+ <name>Camel :: Fat-JAR Main</name>
<description>Main to run Camel as Fat-Jar standalone</description>
<properties>
diff --git a/dsl/camel-fatjar-main/src/generated/resources/META-INF/services/org/apache/camel/other.properties b/dsl/camel-fatjar-main/src/generated/resources/META-INF/services/org/apache/camel/other.properties
index 6602ddfbc7c..a6f7ec08656 100644
--- a/dsl/camel-fatjar-main/src/generated/resources/META-INF/services/org/apache/camel/other.properties
+++ b/dsl/camel-fatjar-main/src/generated/resources/META-INF/services/org/apache/camel/other.properties
@@ -3,5 +3,5 @@ name=fatjar-main
groupId=org.apache.camel
artifactId=camel-fatjar-main
version=3.17.0-SNAPSHOT
-projectName=Camel :: Far-JAR Main
+projectName=Camel :: Fat-JAR Main
projectDescription=Main to run Camel as Fat-Jar standalone
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/manifest.tmpl b/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/manifest.tmpl
index dcf6c48af21..2b4a9b85089 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/manifest.tmpl
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/manifest.tmpl
@@ -1,5 +1,5 @@
Manifest-Version: 1.0
-Implementation-Title: Camel :: Camel Far-JAR Runner
+Implementation-Title: Camel :: Camel Fat-JAR Runner
Implementation-Vendor: The Apache Software Foundation
Implementation-Version: {{ .Version }}
Main-Class: com.needhamsoftware.unojar.Boot
[camel] 04/04: CAMEL-18014: camel-java-dsl - Allow to capture compiled byte code
Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
commit 693ecd9d23d961fe7cbe2f79e989bada01e90999
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Tue Apr 26 18:20:39 2022 +0200
CAMEL-18014: camel-java-dsl - Allow to capture compiled byte code
---
.../camel/dsl/java/joor/ByteArrayClassLoader.java | 43 ++++++++++++++++++++++
.../dsl/java/joor/ClassRoutesBuilderLoader.java | 2 +-
.../apache/camel/dsl/java/joor/MultiCompile.java | 22 -----------
3 files changed, 44 insertions(+), 23 deletions(-)
diff --git a/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/ByteArrayClassLoader.java b/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/ByteArrayClassLoader.java
new file mode 100644
index 00000000000..da1dd726116
--- /dev/null
+++ b/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/ByteArrayClassLoader.java
@@ -0,0 +1,43 @@
+/*
+ * 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.dsl.java.joor;
+
+import java.util.Map;
+
+/**
+ * {@link ClassLoader} that loads byte code from a byte array.
+ */
+final class ByteArrayClassLoader extends ClassLoader {
+ private final Map<String, byte[]> classes;
+
+ public ByteArrayClassLoader(Map<String, byte[]> classes) {
+ super(ByteArrayClassLoader.class.getClassLoader());
+
+ this.classes = classes;
+ }
+
+ @Override
+ protected Class<?> findClass(String name) throws ClassNotFoundException {
+ byte[] bytes = classes.get(name);
+
+ if (bytes == null) {
+ return super.findClass(name);
+ } else {
+ return defineClass(name, bytes, 0, bytes.length);
+ }
+ }
+}
diff --git a/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/ClassRoutesBuilderLoader.java b/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/ClassRoutesBuilderLoader.java
index b94a690026c..aacf7b211b8 100644
--- a/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/ClassRoutesBuilderLoader.java
+++ b/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/ClassRoutesBuilderLoader.java
@@ -45,7 +45,7 @@ public class ClassRoutesBuilderLoader extends ExtendedRouteBuilderLoaderSupport
}
}
- MultiCompile.ByteArrayClassLoader cl = new MultiCompile.ByteArrayClassLoader(byteCodes);
+ ByteArrayClassLoader cl = new ByteArrayClassLoader(byteCodes);
// instantiate classes from the byte codes
for (Resource res : resources) {
diff --git a/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/MultiCompile.java b/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/MultiCompile.java
index 3f59f0b6bbf..b2443958a7f 100644
--- a/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/MultiCompile.java
+++ b/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/MultiCompile.java
@@ -197,28 +197,6 @@ public final class MultiCompile {
return sf != null ? sf.getDeclaringClass() : null;
}
- /* [java-9] */
- static final class ByteArrayClassLoader extends ClassLoader {
- private final Map<String, byte[]> classes;
-
- ByteArrayClassLoader(Map<String, byte[]> classes) {
- super(ByteArrayClassLoader.class.getClassLoader());
-
- this.classes = classes;
- }
-
- @Override
- protected Class<?> findClass(String name) throws ClassNotFoundException {
- byte[] bytes = classes.get(name);
-
- if (bytes == null) {
- return super.findClass(name);
- } else {
- return defineClass(name, bytes, 0, bytes.length);
- }
- }
- }
-
static final class JavaFileObject extends SimpleJavaFileObject {
final ByteArrayOutputStream os = new ByteArrayOutputStream();