This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel.git
commit e7c93fcd0308488d88d935e9e2471346a37c3385 Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Sat Jun 15 22:11:26 2019 +0200 CAMEL-13647: Allow to do autowrire by classpath. Quick and dirty prototype. --- .../java/org/apache/camel/maven/AutowireMojo.java | 76 ++++++++++++++-------- examples/camel-example-main/pom.xml | 2 +- 2 files changed, 51 insertions(+), 27 deletions(-) diff --git a/catalog/camel-main-maven-plugin/src/main/java/org/apache/camel/maven/AutowireMojo.java b/catalog/camel-main-maven-plugin/src/main/java/org/apache/camel/maven/AutowireMojo.java index b57c8fd..02616f7 100644 --- a/catalog/camel-main-maven-plugin/src/main/java/org/apache/camel/maven/AutowireMojo.java +++ b/catalog/camel-main-maven-plugin/src/main/java/org/apache/camel/maven/AutowireMojo.java @@ -17,6 +17,7 @@ package org.apache.camel.maven; import java.io.File; +import java.io.FileOutputStream; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; @@ -82,6 +83,12 @@ public class AutowireMojo extends AbstractExecMojo { @Parameter(property = "camel.logClasspath", defaultValue = "false") protected boolean logClasspath; + /** + * The output directory for generated autowire file + */ + @Parameter(readonly = true, defaultValue = "${project.build.directory}/classes/META-INF/services/org/apache/camel/") + protected File outFolder; + @Component private ArtifactFactory artifactFactory; @@ -94,7 +101,7 @@ public class AutowireMojo extends AbstractExecMojo { @Parameter(property = "project.remoteArtifactRepositories") private List remoteRepositories; - private ClassLoader classLoader; + private transient ClassLoader classLoader; // CHECKSTYLE:OFF @Override @@ -134,33 +141,55 @@ public class AutowireMojo extends AbstractExecMojo { // find all Camel components on classpath and check in the camel-catalog for all component options // then check each option if its a complex type and an interface // and if so scan class-path and find the single class implementing this interface - // write this to META-INF/services/org/apache/camel/autowire-by-classpath + // write this to META-INF/services/org/apache/camel/autowire.properties // find all Camel components on classpath Set<String> components = resolveCamelComponentsFromClasspath(); if (components.isEmpty()) { getLog().warn("No Camel components discovered in classpath"); + return; } else { getLog().info("Discovered " + components.size() + " Camel components from classpath: " + components); } + // build index of classes on classpath + getLog().debug("Indexing classes on classpath"); Reflections reflections = new Reflections(new ConfigurationBuilder() .addUrls(ClasspathHelper.forClassLoader(classLoader)) .addClassLoader(classLoader) .setScanners(new SubTypesScanner())); + List<String> autowires = findAutowireComponentOptionsByClasspath(catalog, components, reflections); + if (!autowires.isEmpty()) { + outFolder.mkdirs(); + File file = new File(outFolder, "autowire.properties"); + try { + FileOutputStream fos = new FileOutputStream(file, false); + fos.write("# Generated by camel build tools\n".getBytes()); + for (String line : autowires) { + fos.write(line.getBytes()); + fos.write("\n".getBytes()); + } + IOHelper.close(fos); + getLog().info("Created file: " + file + " (autowire by classpath: " + autowires.size() + ")"); + } catch (Throwable e) { + throw new MojoFailureException("Cannot write to file " + file + " due " + e.getMessage(), e); + } + } + } + + protected List<String> findAutowireComponentOptionsByClasspath(CamelCatalog catalog, Set<String> components, Reflections reflections) { List<String> autowires = new ArrayList<>(); for (String componentName : components) { -getLog().info("Autowiring Camel component: " + componentName); + getLog().debug("Autowiring Camel component: " + componentName); + String json = catalog.componentJSonSchema(componentName); if (json == null) { - getLog().warn("Cannot find component JSon metadata for component: " + componentName); + getLog().debug("Cannot find component JSon metadata for component: " + componentName); continue; } - - List<Map<String, String>> rows = JSonSchemaHelper.parseJsonSchema("componentProperties", json, true); Set<String> names = JSonSchemaHelper.getNames(rows); for (String name : names) { @@ -168,7 +197,6 @@ getLog().info("Autowiring Camel component: " + componentName); String type = row.get("type"); String javaType = safeJavaType(row.get("javaType")); if ("object".equals(type)) { - // resolve javatype as class try { Class clazz = classLoader.loadClass(javaType); if (clazz.isInterface()) { @@ -178,32 +206,28 @@ getLog().info("Autowiring Camel component: " + componentName); if (classes.size() == 1) { Class cls = classes.iterator().next(); if (isValidAutowireClass(cls)) { - String line = "camel.component." + componentName + "." + name + "=#class:" + cls; + String line = "camel.component." + componentName + "." + name + "=#class:" + cls.getName(); getLog().debug(line); autowires.add(line); } } else if (classes.size() > 1) { - getLog().debug("Found " + classes.size() + " for autowire: " + componentName + "." + name + " -> " + classes); + getLog().debug("Found " + classes.size() + " for autowire: " + componentName + "." + name + ". Cannot chose one class: " + classes); } } } catch (Exception e) { - getLog().warn("Cannot load class: " + name, e); + getLog().debug("Cannot load class: " + name, e); // ignore } } } } - if (!autowires.isEmpty()) { - // write the file - getLog().info("" + autowires); - } + return autowires; } - protected boolean isValidAutowireClass(Class clazz) { - // skip all from Apache Camel as they would be default anyway + // skip all from Apache Camel and regular JDK as they would be default anyway return !clazz.getName().startsWith("org.apache.camel"); } @@ -215,10 +239,6 @@ getLog().info("Autowiring Camel component: " + componentName); return javaType; } - // autowire - // quartz2.xxxx=ddddd. - // - protected Set<String> resolveCamelComponentsFromClasspath() throws MojoFailureException { Set<String> components = new TreeSet<>(); try { @@ -237,9 +257,9 @@ getLog().info("Autowiring Camel component: " + componentName); IOHelper.close(is); } } catch (Throwable e) { - // error - throw new MojoFailureException("Error during scanning", e); + throw new MojoFailureException("Error during discovering Camel components from classpath due " + e.getMessage(), e); } + return components; } @@ -270,10 +290,15 @@ getLog().info("Autowiring Camel component: " + componentName); * Set up a classloader for scanning */ private ClassLoader getClassLoader() throws MalformedURLException, MojoExecutionException { + Set<URL> classpathURLs = new LinkedHashSet<>(); + + // add project classpath + URL mainClasses = new File(project.getBuild().getOutputDirectory()).toURI().toURL(); + classpathURLs.add(mainClasses); + + // add maven dependencies Set<Artifact> deps = project.getArtifacts(); deps.addAll(getAllNonTestScopedDependencies()); - - Set<URL> classpathURLs = new LinkedHashSet<>(); for (Artifact dep : deps) { File file = dep.getFile(); if (file != null) { @@ -284,7 +309,7 @@ getLog().info("Autowiring Camel component: " + componentName); if (logClasspath) { getLog().info("Classpath:"); for (URL url : classpathURLs) { - getLog().info(" " + url.getFile().toString()); + getLog().info(" " + url.getFile()); } } return new URLClassLoader(classpathURLs.toArray(new URL[classpathURLs.size()])); @@ -368,5 +393,4 @@ getLog().info("Autowiring Camel component: " + componentName); return artifacts; } - } diff --git a/examples/camel-example-main/pom.xml b/examples/camel-example-main/pom.xml index 384af5f..6a4c5bb 100644 --- a/examples/camel-example-main/pom.xml +++ b/examples/camel-example-main/pom.xml @@ -102,7 +102,7 @@ <artifactId>camel-main-maven-plugin</artifactId> <version>${project.version}</version> <configuration> - <logClasspath>true</logClasspath> + <logClasspath>false</logClasspath> </configuration> </plugin>