From 22acfecf48725beefcd9844199ced95e31389775 Mon Sep 17 00:00:00 2001 From: Paul Kofmann Date: Mon, 30 Jan 2023 15:56:46 +0100 Subject: [PATCH] Support specifying classpath for additional velocity tool classes --- .../plugin/avro/GenerateAvroJavaTask.java | 44 +++++++++++++++---- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/github/davidmc24/gradle/plugin/avro/GenerateAvroJavaTask.java b/src/main/java/com/github/davidmc24/gradle/plugin/avro/GenerateAvroJavaTask.java index 6415f09..75c6406 100644 --- a/src/main/java/com/github/davidmc24/gradle/plugin/avro/GenerateAvroJavaTask.java +++ b/src/main/java/com/github/davidmc24/gradle/plugin/avro/GenerateAvroJavaTask.java @@ -18,11 +18,11 @@ import java.io.File; import java.io.IOException; import java.lang.reflect.InvocationTargetException; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; import java.nio.charset.Charset; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; import javax.inject.Inject; import org.apache.avro.Conversion; @@ -42,10 +42,8 @@ import org.gradle.api.provider.Property; import org.gradle.api.provider.Provider; import org.gradle.api.specs.NotSpec; -import org.gradle.api.tasks.CacheableTask; -import org.gradle.api.tasks.Input; +import org.gradle.api.tasks.*; import org.gradle.api.tasks.Optional; -import org.gradle.api.tasks.TaskAction; /** * Task to generate Java source files based on Avro protocol files and Avro schema files using {@link Protocol} and @@ -54,6 +52,7 @@ @SuppressWarnings("WeakerAccess") @CacheableTask public class GenerateAvroJavaTask extends OutputDirTask { + private FileCollection classpath; private static Set SUPPORTED_EXTENSIONS = new SetBuilder().add(Constants.PROTOCOL_EXTENSION).add(Constants.SCHEMA_EXTENSION).build(); @@ -79,6 +78,7 @@ public class GenerateAvroJavaTask extends OutputDirTask { @Inject public GenerateAvroJavaTask(ObjectFactory objects) { super(); + this.classpath = GradleCompatibility.createConfigurableFileCollection(getProject()); this.outputCharacterEncoding = objects.property(String.class); this.stringType = objects.property(String.class).convention(Constants.DEFAULT_STRING_TYPE); this.fieldVisibility = objects.property(String.class).convention(Constants.DEFAULT_FIELD_VISIBILITY); @@ -103,6 +103,19 @@ public GenerateAvroJavaTask(ObjectFactory objects) { this.resolver = new SchemaResolver(projectLayout, getLogger()); } + public void setClasspath(FileCollection classpath) { + this.classpath = classpath; + } + + public void classpath(Object... paths) { + this.classpath.plus(getProject().files(paths)); + } + + @Classpath + public FileCollection getClasspath() { + return this.classpath; + } + @Optional @Input public Property getOutputCharacterEncoding() { @@ -340,10 +353,11 @@ private void compile(SpecificCompiler compiler, File sourceFile) throws IOExcept compiler.setTemplateDir(getTemplateDirectory().get()); } if (getAdditionalVelocityToolClasses().isPresent()) { + ClassLoader loader = assembleClassLoader(); List tools = getAdditionalVelocityToolClasses().get().stream() .map(s -> { try { - return Class.forName(s); + return Class.forName(s, true, loader); } catch (ClassNotFoundException e) { throw new RuntimeException("unable to load velocity tool class " + s, e); } @@ -394,4 +408,18 @@ private void registerLogicalTypes() { private void registerCustomConversions(SpecificCompiler compiler) { customConversions.get().forEach(compiler::addCustomConversion); } + + private ClassLoader assembleClassLoader() { + getLogger().debug("Using classpath: {}", classpath.getFiles()); + List urls = new LinkedList<>(); + for (File file : classpath) { + try { + urls.add(file.toURI().toURL()); + } catch (MalformedURLException e) { + getLogger().debug(e.getMessage()); + } + } + // No parent classloader; either it's in the specified classpath or it shouldn't be resolved. + return new URLClassLoader(urls.toArray(new URL[0]), null); + } }