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 2019/06/07 06:39:34 UTC

[camel] branch endpoint-dsl updated: Clean up code a bit

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

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


The following commit(s) were added to refs/heads/endpoint-dsl by this push:
     new 44e35b2  Clean up code a bit
44e35b2 is described below

commit 44e35b26eaa6492232c65d6abb2a6b6534bfcc49
Author: Guillaume Nodet <gn...@gmail.com>
AuthorDate: Fri Jun 7 08:39:07 2019 +0200

    Clean up code a bit
---
 .../camel/maven/packaging/DynamicClassLoader.java  |  63 +++++++
 .../camel/maven/packaging/EndpointDslMojo.java     | 185 +++++++++------------
 .../packaging/SpringBootAutoConfigurationMojo.java |  35 +---
 3 files changed, 140 insertions(+), 143 deletions(-)

diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/DynamicClassLoader.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/DynamicClassLoader.java
new file mode 100644
index 0000000..adf4330
--- /dev/null
+++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/DynamicClassLoader.java
@@ -0,0 +1,63 @@
+/*
+ * 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.maven.packaging;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Iterator;
+import java.util.List;
+
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Opcodes;
+
+class DynamicClassLoader extends URLClassLoader {
+
+    public DynamicClassLoader(URL[] urls, ClassLoader parent) {
+        super(urls, parent);
+    }
+
+    public static DynamicClassLoader createDynamicClassLoader(List<String> classpathElements) {
+        final URL[] urls = new URL[classpathElements.size()];
+        int i = 0;
+        for (Iterator<?> it = classpathElements.iterator(); it.hasNext(); i++) {
+            try {
+                urls[i] = new File((String)it.next()).toURI().toURL();
+            } catch (MalformedURLException e) {
+                throw new RuntimeException(e.getMessage(), e);
+            }
+        }
+        final ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+        return new DynamicClassLoader(urls, tccl != null ? tccl : DynamicClassLoader.class.getClassLoader());
+    }
+
+    public Class defineClass(String name, byte[] data) {
+        return super.defineClass(name, data, 0, data.length);
+    }
+
+    public Class generateDummyClass(String clazzName) {
+        try {
+            return loadClass(clazzName);
+        } catch (ClassNotFoundException e) {
+            ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
+            cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, clazzName.replace('.', '/'), null, "java/lang/Object", null);
+            cw.visitEnd();
+            return defineClass(clazzName, cw.toByteArray());
+        }
+    }
+}
diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/EndpointDslMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/EndpointDslMojo.java
index deec1dc..b412fe5 100644
--- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/EndpointDslMojo.java
+++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/EndpointDslMojo.java
@@ -23,13 +23,8 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.lang.reflect.Array;
 import java.lang.reflect.Field;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLClassLoader;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -49,12 +44,10 @@ import org.apache.camel.maven.packaging.srcgen.GenericType;
 import org.apache.camel.maven.packaging.srcgen.GenericType.BoundType;
 import org.apache.camel.maven.packaging.srcgen.JavaClass;
 import org.apache.camel.maven.packaging.srcgen.Method;
-import org.apache.camel.maven.packaging.srcgen.Property;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
 import org.apache.camel.spi.UriParams;
 import org.apache.camel.spi.UriPath;
-import org.apache.camel.spi.annotations.Component;
 import org.apache.maven.plugin.AbstractMojo;
 import org.apache.maven.plugin.MojoExecutionException;
 import org.apache.maven.plugin.MojoFailureException;
@@ -64,9 +57,6 @@ import org.apache.maven.plugins.annotations.Parameter;
 import org.apache.maven.plugins.annotations.ResolutionScope;
 import org.apache.maven.project.MavenProject;
 import org.jboss.forge.roaster.model.util.Strings;
-import org.objectweb.asm.ClassWriter;
-import org.objectweb.asm.Opcodes;
-import org.springframework.boot.liquibase.SpringPackageScanClassResolver;
 
 import static org.apache.camel.maven.packaging.AbstractGeneratorMojo.updateResource;
 import static org.apache.camel.maven.packaging.JSonSchemaHelper.getSafeValue;
@@ -80,23 +70,21 @@ import static org.apache.camel.maven.packaging.PackageHelper.loadText;
 @Mojo(name = "generate-endpoint-dsl", threadSafe = true, requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME, defaultPhase = LifecyclePhase.PROCESS_CLASSES)
 public class EndpointDslMojo extends AbstractMojo {
 
-    private static final Map<String, String> PRIMITIVEMAP;
+    private static final Map<String, Class<?>> PRIMITIVEMAP;
 
     static {
         PRIMITIVEMAP = new HashMap<>();
-        PRIMITIVEMAP.put("boolean", "java.lang.Boolean");
-        PRIMITIVEMAP.put("char", "java.lang.Character");
-        PRIMITIVEMAP.put("long", "java.lang.Long");
-        PRIMITIVEMAP.put("int", "java.lang.Integer");
-        PRIMITIVEMAP.put("integer", "java.lang.Integer");
-        PRIMITIVEMAP.put("byte", "java.lang.Byte");
-        PRIMITIVEMAP.put("short", "java.lang.Short");
-        PRIMITIVEMAP.put("double", "java.lang.Double");
-        PRIMITIVEMAP.put("float", "java.lang.Float");
+        PRIMITIVEMAP.put("boolean", java.lang.Boolean.class);
+        PRIMITIVEMAP.put("char", java.lang.Character.class);
+        PRIMITIVEMAP.put("long", java.lang.Long.class);
+        PRIMITIVEMAP.put("int", java.lang.Integer.class);
+        PRIMITIVEMAP.put("integer", java.lang.Integer.class);
+        PRIMITIVEMAP.put("byte", java.lang.Byte.class);
+        PRIMITIVEMAP.put("short", java.lang.Short.class);
+        PRIMITIVEMAP.put("double", java.lang.Double.class);
+        PRIMITIVEMAP.put("float", java.lang.Float.class);
     }
 
-    private static final String[] IGNORE_MODULES = {/* Non-standard -> */ };
-
     /**
      * The maven project.
      */
@@ -119,19 +107,14 @@ public class EndpointDslMojo extends AbstractMojo {
 
     @Override
     public void execute() throws MojoExecutionException, MojoFailureException {
-        // Do not generate code for ignored module
-        if (Arrays.asList(IGNORE_MODULES).contains(project.getArtifactId())) {
-            getLog().info("Component auto-configuration will not be created: component contained in the ignore list");
-            return;
+        try {
+            projectClassLoader = DynamicClassLoader.createDynamicClassLoader(project.getTestClasspathElements());
+        } catch (org.apache.maven.artifact.DependencyResolutionRequiredException e) {
+            throw new RuntimeException(e.getMessage(), e);
         }
 
-        executeAll();
-    }
-
-    private void executeAll() throws MojoExecutionException, MojoFailureException {
         Map<File, Supplier<String>> files = PackageHelper.findJsonFiles(buildDir, p -> p.isDirectory() || p.getName().endsWith(".json")).stream()
-            .collect(Collectors.toMap(Function.identity(), s -> cache(() -> loadJson(s))));
-
+                .collect(Collectors.toMap(Function.identity(), s -> cache(() -> loadJson(s))));
         executeComponent(files);
     }
 
@@ -146,7 +129,6 @@ public class EndpointDslMojo extends AbstractMojo {
     private static <T> Supplier<T> cache(Supplier<T> supplier) {
         return new Supplier<T>() {
             T value;
-
             @Override
             public T get() {
                 if (value == null) {
@@ -179,11 +161,10 @@ public class EndpointDslMojo extends AbstractMojo {
             Map<String, List<ComponentModel>> grModels = allModels.stream().collect(Collectors.groupingBy(ComponentModel::getJavaType));
             for (String componentClass : grModels.keySet()) {
                 List<ComponentModel> compModels = grModels.get(componentClass);
-                ComponentModel model = compModels.get(0); // They should be
-                                                          // equivalent
+                ComponentModel model = compModels.get(0); // They should be equivalent
                 List<String> aliases = compModels.stream().map(ComponentModel::getScheme).sorted().collect(Collectors.toList());
 
-                 String pkg = "org.apache.camel.model.endpoint";
+                String pkg = "org.apache.camel.model.endpoint";
 
                 String overrideComponentName = null;
                 if (aliases.size() > 1) {
@@ -197,31 +178,24 @@ public class EndpointDslMojo extends AbstractMojo {
     }
 
     private void createEndpointDsl(String packageName, ComponentModel model, String overrideComponentName) throws MojoFailureException {
-        int pos = model.getJavaType().lastIndexOf(".");
-        String name = model.getJavaType().substring(pos + 1);
-        name = name.replace("Component", "Endpoint");
-
-        if (model.getJavaType().equals("org.apache.camel.component.atmosphere.websocket.WebsocketComponent")) {
-            name = "AtmosphereWebsocketEndpoint";
-        } else if (model.getJavaType().equals("org.apache.camel.component.zookeepermaster.MasterComponent")) {
-            name = "ZooKeeperMasterEndpoint";
-        }
-
-        Class<?> realComponentClass = loadClass(model.getJavaType());
-        Class<?> realEndpointClass = findEndpointClass(realComponentClass);
+        String componentClassName = model.getJavaType();
+        String endpointName = getEndpointName(componentClassName);
+        Class<?> realComponentClass = loadClass(componentClassName);
+        Class<?> realEndpointClass = loadClass(findEndpointClassName(componentClassName));
 
         final JavaClass javaClass = new JavaClass(getProjectClassLoader());
         javaClass.setPackage(packageName);
-        javaClass.setName(name);
+        javaClass.setName(endpointName);
         javaClass.addImport("org.apache.camel.model.EndpointDefinition");
 
         Map<String, JavaClass> enumClasses = new HashMap<>();
 
+        String commonName = endpointName.replace("Endpoint", "Common");
         JavaClass commonClass = javaClass.addNestedType().setPublic().setStatic(true);
-        commonClass.setName(name.replace("Endpoint", "Common") + "<T extends EndpointDefinition>");
+        commonClass.setName(commonName + "<T extends EndpointDefinition>");
         commonClass.extendSuperType("EndpointDefinition<T>");
         commonClass.addMethod().setConstructor(true)
-                .setName(name.replace("Endpoint", "Common"))
+                .setName(commonName)
                 .addParameter(String.class, "path")
                 .setBody("super(\"" + model.getScheme() + "\", path);");
         generateDummyClass(commonClass.getCanonicalName());
@@ -230,12 +204,13 @@ public class EndpointDslMojo extends AbstractMojo {
         if (realEndpointClass.getAnnotation(UriEndpoint.class).producerOnly()) {
             consumerClass = null;
         } else {
+            String consumerName = endpointName.replace("Endpoint", "Consumer");
             consumerClass = javaClass.addNestedType().setPublic().setStatic(true);
-            consumerClass.setName(name.replace("Endpoint", "Consumer"));
-            consumerClass.extendSuperType(name.replace("Endpoint", "Common") + "<" + name.replace("Endpoint", "Consumer") + ">");
+            consumerClass.setName(consumerName);
+            consumerClass.extendSuperType(commonName + "<" + consumerName + ">");
             consumerClass.implementInterface("EndpointDefinition.Consumer");
             consumerClass.addMethod().setConstructor(true).setPublic()
-                    .setName(name.replace("Endpoint", "Consumer"))
+                    .setName(consumerName)
                     .addParameter(String.class, "path")
                     .setBody("super(path);");
             generateDummyClass(consumerClass.getCanonicalName());
@@ -245,12 +220,13 @@ public class EndpointDslMojo extends AbstractMojo {
         if (realEndpointClass.getAnnotation(UriEndpoint.class).consumerOnly()) {
             producerClass = null;
         } else {
+            String producerName = endpointName.replace("Endpoint", "Producer");
             producerClass = javaClass.addNestedType().setPublic().setStatic(true);
-            producerClass.setName(name.replace("Endpoint", "Producer"));
-            producerClass.extendSuperType(name.replace("Endpoint", "Common") + "<" + name.replace("Endpoint", "Producer") + ">");
+            producerClass.setName(producerName);
+            producerClass.extendSuperType(commonName + "<" + producerName + ">");
             producerClass.implementInterface("EndpointDefinition.Producer");
             producerClass.addMethod().setConstructor(true).setPublic()
-                    .setName(name.replace("Endpoint", "Producer"))
+                    .setName(producerName)
                     .addParameter(String.class, "path")
                     .setBody("super(path);");
             generateDummyClass(producerClass.getCanonicalName());
@@ -267,7 +243,6 @@ public class EndpointDslMojo extends AbstractMojo {
         javaClass.addAnnotation(Generated.class.getName())
                 .setStringValue("value", EndpointDslMojo.class.getName());
 
-        boolean pathSet = false;
         for (EndpointOptionModel option : model.getEndpointOptions()) {
 
             JavaClass target = commonClass;
@@ -278,6 +253,9 @@ public class EndpointDslMojo extends AbstractMojo {
                     target = consumerClass;
                 }
             }
+            if (target == null) {
+                throw new IllegalArgumentException("Illegal label " + option.getLabel() + " for option " + option.getName());
+            }
 
             GenericType ogtype;
             GenericType gtype;
@@ -294,7 +272,7 @@ public class EndpointDslMojo extends AbstractMojo {
             String fluentBuilderTypeShortName = target == commonClass ? "T" : target.getName();
             Method fluent = target.addMethod().setPublic().setName(option.getName())
                     .setReturnType(new GenericType(loadClass(fluentBuilderTypeName)) )
-                    .addParameter(PRIMITIVEMAP.containsKey(ogtype.toString()) ? ogtype : gtype, option.getName())
+                    .addParameter(isPrimitive(ogtype.toString()) ? ogtype : gtype, option.getName())
                     .setBody("this.properties.put(\"" + option.getName() + "\", " + option.getName() + ");\n" +
                              "return (" + fluentBuilderTypeShortName + ") this;\n");
             if ("true".equals(option.getDeprecated())) {
@@ -312,20 +290,41 @@ public class EndpointDslMojo extends AbstractMojo {
 
         javaClass.removeImport("T");
 
-        String fileName = packageName.replaceAll("\\.", "\\/") + "/" + name + ".java";
+        String fileName = packageName.replaceAll("\\.", "\\/") + "/" + endpointName + ".java";
         writeSourceIfChanged(javaClass, fileName, false);
     }
 
-    private Class<?> findEndpointClass(Class<?> componentClass) {
-        String endpointName = componentClass.getCanonicalName().replaceFirst("Component", "Endpoint");
-        if ("org.apache.camel.component.disruptor.vm.DisruptorVmEndpoint".equals(endpointName)) {
-            endpointName = "org.apache.camel.component.disruptor.DisruptorEndpoint";
-        } else if ("org.apache.camel.component.etcd.EtcdEndpoint".equals(endpointName)) {
-            endpointName = "org.apache.camel.component.etcd.AbstractEtcdPollingEndpoint";
-        } else if ("org.apache.camel.websocket.jsr356.JSR356WebSocketEndpoint".equals(endpointName)) {
-            endpointName = "org.apache.camel.websocket.jsr356.JSR356Endpoint";
+    private String getEndpointName(String type) {
+        int pos = type.lastIndexOf(".");
+        String name = type.substring(pos + 1).replace("Component", "Endpoint");
+        //
+        // HACKS
+        //
+        switch (type) {
+            case "org.apache.camel.component.atmosphere.websocket.WebsocketComponent":
+                return "AtmosphereWebsocketEndpoint";
+            case "org.apache.camel.component.zookeepermaster.MasterComponent":
+                return "ZooKeeperMasterEndpoint";
+            default:
+                return name;
+        }
+    }
+
+    private String findEndpointClassName(String type) {
+        String endpointName = type.replaceFirst("Component", "Endpoint");
+        //
+        // HACKS
+        //
+        switch (type) {
+            case "org.apache.camel.component.disruptor.vm.DisruptorVmComponent":
+                return "org.apache.camel.component.disruptor.DisruptorEndpoint";
+            case "org.apache.camel.component.etcd.EtcdComponent":
+                return "org.apache.camel.component.etcd.AbstractEtcdPollingEndpoint";
+            case "org.apache.camel.websocket.jsr356.JSR356WebSocketComponent":
+                return "org.apache.camel.websocket.jsr356.JSR356Endpoint";
+            default:
+                return endpointName;
         }
-        return loadClass(endpointName);
     }
 
     private Field findField(Class<?> realComponentClass, Class<?> realEndpointClass, EndpointOptionModel option) throws NoSuchFieldException {
@@ -417,7 +416,7 @@ public class EndpointDslMojo extends AbstractMojo {
         }
         // Primitive
         if (isPrimitive(type)) {
-            return new GenericType(loadClass(PRIMITIVEMAP.get(type)));
+            return new GenericType(PRIMITIVEMAP.get(type));
         }
         // Extends
         if (type.startsWith("? extends ")) {
@@ -498,48 +497,12 @@ public class EndpointDslMojo extends AbstractMojo {
                 || type.matches("org\\.apache\\.camel\\.(spi\\.)?([A-Za-z]+)");
     }
 
-    protected DynamicClassLoader getProjectClassLoader() {
-        if (projectClassLoader == null) {
-            final List<?> classpathElements;
-            try {
-                classpathElements = project.getTestClasspathElements();
-            } catch (org.apache.maven.artifact.DependencyResolutionRequiredException e) {
-                throw new RuntimeException(e.getMessage(), e);
-            }
-            final URL[] urls = new URL[classpathElements.size()];
-            int i = 0;
-            for (Iterator<?> it = classpathElements.iterator(); it.hasNext(); i++) {
-                try {
-                    urls[i] = new File((String)it.next()).toURI().toURL();
-                } catch (MalformedURLException e) {
-                    throw new RuntimeException(e.getMessage(), e);
-                }
-            }
-            final ClassLoader tccl = Thread.currentThread().getContextClassLoader();
-            projectClassLoader = new DynamicClassLoader(urls, tccl != null ? tccl : getClass().getClassLoader());
-        }
-        return projectClassLoader;
-    }
-
-    static class DynamicClassLoader extends URLClassLoader {
-        public DynamicClassLoader(URL[] urls, ClassLoader parent) {
-            super(urls, parent);
-        }
-
-        public Class defineClass(String name, byte[] data) {
-            return super.defineClass(name, data, 0, data.length);
-        }
+    private Class generateDummyClass(String clazzName) {
+        return getProjectClassLoader().generateDummyClass(clazzName);
     }
 
-    private Class generateDummyClass(String clazzName) {
-        try {
-            return getProjectClassLoader().loadClass(clazzName);
-        } catch (ClassNotFoundException e) {
-            ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
-            cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, clazzName.replace('.', '/'), null, "java/lang/Object", null);
-            cw.visitEnd();
-            return getProjectClassLoader().defineClass(clazzName, cw.toByteArray());
-        }
+    private DynamicClassLoader getProjectClassLoader() {
+        return projectClassLoader;
     }
 
     private static String loadComponentJson(Map<File, Supplier<String>> jsonFiles, String componentName) {
@@ -645,7 +608,7 @@ public class EndpointDslMojo extends AbstractMojo {
     }
 
     private void writeSourceIfChanged(String source, String fileName) throws MojoFailureException {
-        File core = findCamelCoreDirectory(project.getBasedir());
+        File core = findCamelCoreDirectory(baseDir);
 
         File target = new File(new File(core, "src/main/java"), fileName);
 
diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SpringBootAutoConfigurationMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SpringBootAutoConfigurationMojo.java
index 8d25d38..5839057 100644
--- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SpringBootAutoConfigurationMojo.java
+++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SpringBootAutoConfigurationMojo.java
@@ -23,9 +23,6 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.lang.reflect.Modifier;
 import java.lang.reflect.Type;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLClassLoader;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
@@ -34,7 +31,6 @@ import java.util.Arrays;
 import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.LinkedHashSet;
 import java.util.LinkedList;
 import java.util.List;
@@ -78,8 +74,6 @@ import org.apache.maven.plugins.annotations.Parameter;
 import org.apache.maven.plugins.annotations.ResolutionScope;
 import org.apache.maven.project.MavenProject;
 import org.jboss.forge.roaster.model.util.Strings;
-import org.objectweb.asm.ClassWriter;
-import org.objectweb.asm.Opcodes;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.config.ConfigurableBeanFactory;
 import org.springframework.boot.autoconfigure.AutoConfigureAfter;
@@ -1092,23 +1086,13 @@ public class SpringBootAutoConfigurationMojo extends AbstractMojo {
 
     protected DynamicClassLoader getProjectClassLoader() {
         if (projectClassLoader == null) {
-            final List<?> classpathElements;
+            final List<String> classpathElements;
             try {
                 classpathElements = project.getTestClasspathElements();
             } catch (org.apache.maven.artifact.DependencyResolutionRequiredException e) {
                 throw new RuntimeException(e.getMessage(), e);
             }
-            final URL[] urls = new URL[classpathElements.size()];
-            int i = 0;
-            for (Iterator<?> it = classpathElements.iterator(); it.hasNext(); i++) {
-                try {
-                    urls[i] = new File((String)it.next()).toURI().toURL();
-                } catch (MalformedURLException e) {
-                    throw new RuntimeException(e.getMessage(), e);
-                }
-            }
-            final ClassLoader tccl = Thread.currentThread().getContextClassLoader();
-            projectClassLoader = new DynamicClassLoader(urls, tccl != null ? tccl : getClass().getClassLoader());
+            projectClassLoader = DynamicClassLoader.createDynamicClassLoader(classpathElements);
         }
         return projectClassLoader;
     }
@@ -1523,16 +1507,6 @@ public class SpringBootAutoConfigurationMojo extends AbstractMojo {
         writeSourceIfChanged(javaClass, fileName, true);
     }
 
-    static class DynamicClassLoader extends URLClassLoader {
-        public DynamicClassLoader(URL[] urls, ClassLoader parent) {
-            super(urls, parent);
-        }
-
-        public Class defineClass(String name, byte[] data) {
-            return super.defineClass(name, data, 0, data.length);
-        }
-    }
-
     private void createComponentAutoConfigurationSource(String packageName, ComponentModel model, List<String> componentAliases, String overrideComponentName)
         throws MojoFailureException {
 
@@ -1604,10 +1578,7 @@ public class SpringBootAutoConfigurationMojo extends AbstractMojo {
     }
 
     private Class generateDummyClass(String clazzName) {
-        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
-        cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, clazzName.replace('.', '/'), null, "java/lang/Object", null);
-        cw.visitEnd();
-        return getProjectClassLoader().defineClass(clazzName, cw.toByteArray());
+        return getProjectClassLoader().generateDummyClass(clazzName);
     }
 
     private void createDataFormatAutoConfigurationSource(String packageName, DataFormatModel model, List<String> dataFormatAliases, String overrideDataFormatName)