This is an automated email from the ASF dual-hosted git repository. dblevins pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/tomee-patch-plugin.git
commit c58fe32818e08ebfab14b61354cfb39771d660c2 Author: David Blevins <[email protected]> AuthorDate: Thu Jun 11 19:26:49 2020 -0700 Build a compile-time classpath from the zips being patched --- .../org/apache/tomee/patch/plugin/PatchMojo.java | 301 +++++++++++++-------- 1 file changed, 188 insertions(+), 113 deletions(-) diff --git a/tomee-patch-plugin/src/main/java/org/apache/tomee/patch/plugin/PatchMojo.java b/tomee-patch-plugin/src/main/java/org/apache/tomee/patch/plugin/PatchMojo.java index a237085..ef995d4 100644 --- a/tomee-patch-plugin/src/main/java/org/apache/tomee/patch/plugin/PatchMojo.java +++ b/tomee-patch-plugin/src/main/java/org/apache/tomee/patch/plugin/PatchMojo.java @@ -31,12 +31,14 @@ import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProjectHelper; import org.apache.maven.toolchain.Toolchain; import org.apache.maven.toolchain.ToolchainManager; +import org.apache.tomee.patch.core.Is; import org.codehaus.plexus.compiler.Compiler; import org.codehaus.plexus.compiler.CompilerConfiguration; import org.codehaus.plexus.compiler.CompilerMessage; import org.codehaus.plexus.compiler.CompilerResult; import org.codehaus.plexus.compiler.manager.CompilerManager; import org.codehaus.plexus.compiler.manager.NoSuchCompilerException; +import org.tomitribe.jkta.usage.Dir; import org.tomitribe.util.Files; import org.tomitribe.util.Zips; @@ -48,6 +50,8 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.function.Predicate; +import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -63,10 +67,16 @@ public class PatchMojo extends AbstractMojo { @Parameter(defaultValue = "${project.build.directory}", required = true) private File outputDirectory; - @Parameter(defaultValue = "${project.basedir}/src/main/patch", required = true) + @Parameter(defaultValue = "${project.basedir}/src/patch/java", required = true) private File patchSourceDirectory; /** + * Regex to identify which archives should be matched + */ + @Parameter(defaultValue = "jakartaee9.*\\.zip", required = true) + private String select; + + /** * <p> * Specify the requirements for this jdk toolchain. * This overrules the toolchain selected by the maven-toolchain-plugin. @@ -99,10 +109,17 @@ public class PatchMojo extends AbstractMojo { /** * The target directory of the compiler if fork is true. */ - @Parameter(defaultValue = "${project.build.directory}", required = true, readonly = true) + @Parameter(defaultValue = "${project.build.directory}/patch-classes", required = true, readonly = true) private File buildDirectory; /** + * The directory where we will extract the zips being patched so we can compile the + * patch source against the jars contained within. + */ + @Parameter(defaultValue = "${project.build.directory}/patch-classpath", required = true) + private File patchClasspathDirectory; + + /** * The -encoding argument for the Java compiler. * * @since 2.1 @@ -153,134 +170,192 @@ public class PatchMojo extends AbstractMojo { */ public void execute() throws MojoExecutionException, CompilationFailureException { try { - final List<Artifact> artifacts = Stream.of(getSourceArtifacts()) - .filter(artifact -> artifact.getFile().getName().contains("jakartaee9")) - .collect(Collectors.toList()); + Files.mkdir(patchClasspathDirectory); + + // Select the zip files and jars we'll be potentially patching + final List<Artifact> artifacts = getPatchArtifacts(); - final File archives = new File(outputDirectory, "patch"); - Files.mkdir(archives); + // Extract any zips and return a list of jars + final List<File> jars = prepareJars(artifacts); - Compiler compiler; + compile(patchSourceDirectory, jars); - getLog().debug("Using compiler '" + compilerId + "'."); + } catch (IOException e) { + throw new MojoExecutionException("Error occurred during execution", e); + } + } - try { - compiler = compilerManager.getCompiler(compilerId); - } catch (NoSuchCompilerException e) { - throw new MojoExecutionException("No such compiler '" + e.getCompilerId() + "'."); - } + /** + * Any zip files contained in the Artifact set should be extracted + * Any jar files contained in the Artifact set will be returned as-is + */ + private List<File> prepareJars(final List<Artifact> artifacts) throws IOException { - Toolchain tc = getToolchain(); - if (tc != null) { - getLog().info("Toolchain in maven-compiler-plugin: " + tc); - //TODO somehow shaky dependency between compilerId and tool executable. - executable = tc.findTool(compilerId); + // Extract all zip, war, ear, rar files. Do not extract jar files. + for (final Artifact artifact : artifacts) { + if (isZip(artifact.getFile()) && !isJar(artifact.getFile())) { + Zips.unzip(artifact.getFile(), patchClasspathDirectory); } + } - final CompilerConfiguration compilerConfiguration = new CompilerConfiguration(); - compilerConfiguration.setOutputLocation(outputDirectory.getAbsolutePath()); - compilerConfiguration.setOptimize(false); - compilerConfiguration.setDebug(true); - compilerConfiguration.setParameters(false); - compilerConfiguration.setVerbose(false); - compilerConfiguration.setShowWarnings(false); - compilerConfiguration.setFailOnWarning(false); - compilerConfiguration.setShowDeprecation(false); - compilerConfiguration.setSourceVersion(source); - compilerConfiguration.setTargetVersion(target); - compilerConfiguration.setReleaseVersion(null); - compilerConfiguration.setProc(null); - compilerConfiguration.setSourceLocations(getPatchSourceLocations()); - compilerConfiguration.setAnnotationProcessors(null); - compilerConfiguration.setSourceEncoding(encoding); - compilerConfiguration.setFork(true); - compilerConfiguration.setExecutable(executable); - compilerConfiguration.setWorkingDirectory(basedir); - compilerConfiguration.setCompilerVersion(compilerVersion); - compilerConfiguration.setBuildDirectory(buildDirectory); - compilerConfiguration.setOutputFileName(null); - - final CompilerResult compilerResult; - try { - compilerResult = compiler.performCompile(compilerConfiguration); - } catch (Exception e) { - throw new MojoExecutionException("Fatal error compiling", e); - } + // Collect a list of jars + final List<File> jars = new ArrayList<>(); - List<CompilerMessage> warnings = new ArrayList<>(); - List<CompilerMessage> errors = new ArrayList<>(); - List<CompilerMessage> others = new ArrayList<>(); - for (CompilerMessage message : compilerResult.getCompilerMessages()) { - if (message.getKind() == CompilerMessage.Kind.ERROR) { - errors.add(message); - } else if (message.getKind() == CompilerMessage.Kind.WARNING - || message.getKind() == CompilerMessage.Kind.MANDATORY_WARNING) { - warnings.add(message); - } else { - others.add(message); - } + // Add any artifacts that are already jars + artifacts.stream() + .map(Artifact::getFile) + .filter(File::isFile) + .filter(this::isJar) + .forEach(jars::add); + + // Add any extracted files that are jars + Dir.from(patchClasspathDirectory) + .files() + .filter(File::isFile) + .filter(this::isJar) + .forEach(jars::add); + + return jars; + } + + private boolean isJar(final File file) { + return file.getName().endsWith(".jar"); + } + + private static boolean isZip(final File file) { + return new Is.Zip().accept(file); + } + + private List<Artifact> getPatchArtifacts() { + final Predicate<String> match = Pattern.compile(select).asPredicate(); + return Stream.of(getSourceArtifacts()) + .filter(artifact -> match.test(artifact.getFile().getName())) + .collect(Collectors.toList()); + } + + private void compile(final File patchSourceDirectory, final List<File> jars) throws MojoExecutionException, CompilationFailureException { + + getLog().debug("Using compiler '" + compilerId + "'."); + + final Compiler compiler; + + try { + compiler = compilerManager.getCompiler(compilerId); + } catch (NoSuchCompilerException e) { + throw new MojoExecutionException("No such compiler '" + e.getCompilerId() + "'."); + } + + final Toolchain tc = getToolchain(); + if (tc != null) { + getLog().info("Toolchain in maven-compiler-plugin: " + tc); + //TODO somehow shaky dependency between compilerId and tool executable. + executable = tc.findTool(compilerId); + } + + + final CompilerConfiguration compilerConfiguration = new CompilerConfiguration(); + compilerConfiguration.setOutputLocation(buildDirectory.getAbsolutePath()); + compilerConfiguration.setOptimize(false); + compilerConfiguration.setDebug(true); + compilerConfiguration.setParameters(false); + compilerConfiguration.setVerbose(false); + compilerConfiguration.setShowWarnings(false); + compilerConfiguration.setFailOnWarning(false); + compilerConfiguration.setShowDeprecation(false); + compilerConfiguration.setSourceVersion(source); + compilerConfiguration.setTargetVersion(target); + compilerConfiguration.setReleaseVersion(null); + compilerConfiguration.setProc(null); + compilerConfiguration.setSourceLocations(getPatchSourceLocations()); + compilerConfiguration.setAnnotationProcessors(null); + compilerConfiguration.setSourceEncoding(encoding); + compilerConfiguration.setFork(true); + compilerConfiguration.setExecutable(executable); + compilerConfiguration.setWorkingDirectory(basedir); + compilerConfiguration.setCompilerVersion(compilerVersion); + compilerConfiguration.setBuildDirectory(buildDirectory); + compilerConfiguration.setOutputFileName(null); + + // Add each jar as a classpath entry + jars.stream() + .map(File::getAbsolutePath) + .forEach(compilerConfiguration::addClasspathEntry); + + // Now we can compile! + final CompilerResult compilerResult; + try { + compilerResult = compiler.performCompile(compilerConfiguration); + } catch (Exception e) { + throw new MojoExecutionException("Fatal error compiling", e); + } + + List<CompilerMessage> warnings = new ArrayList<>(); + List<CompilerMessage> errors = new ArrayList<>(); + List<CompilerMessage> others = new ArrayList<>(); + for (CompilerMessage message : compilerResult.getCompilerMessages()) { + if (message.getKind() == CompilerMessage.Kind.ERROR) { + errors.add(message); + } else if (message.getKind() == CompilerMessage.Kind.WARNING + || message.getKind() == CompilerMessage.Kind.MANDATORY_WARNING) { + warnings.add(message); + } else { + others.add(message); } + } - if (true && !compilerResult.isSuccess()) { - for (CompilerMessage message : others) { - assert message.getKind() != CompilerMessage.Kind.ERROR - && message.getKind() != CompilerMessage.Kind.WARNING - && message.getKind() != CompilerMessage.Kind.MANDATORY_WARNING; - getLog().info(message.toString()); - } - if (!warnings.isEmpty()) { - getLog().info("-------------------------------------------------------------"); - getLog().warn("COMPILATION WARNING : "); - getLog().info("-------------------------------------------------------------"); - for (CompilerMessage warning : warnings) { - getLog().warn(warning.toString()); - } - getLog().info(warnings.size() + ((warnings.size() > 1) ? " warnings " : " warning")); - getLog().info("-------------------------------------------------------------"); + if (!compilerResult.isSuccess()) { + for (CompilerMessage message : others) { + assert message.getKind() != CompilerMessage.Kind.ERROR + && message.getKind() != CompilerMessage.Kind.WARNING + && message.getKind() != CompilerMessage.Kind.MANDATORY_WARNING; + getLog().info(message.toString()); + } + if (!warnings.isEmpty()) { + getLog().info("-------------------------------------------------------------"); + getLog().warn("COMPILATION WARNING : "); + getLog().info("-------------------------------------------------------------"); + for (CompilerMessage warning : warnings) { + getLog().warn(warning.toString()); } + getLog().info(warnings.size() + ((warnings.size() > 1) ? " warnings " : " warning")); + getLog().info("-------------------------------------------------------------"); + } - if (!errors.isEmpty()) { - getLog().info("-------------------------------------------------------------"); - getLog().error("COMPILATION ERROR : "); - getLog().info("-------------------------------------------------------------"); - for (CompilerMessage error : errors) { - getLog().error(error.toString()); - } - getLog().info(errors.size() + ((errors.size() > 1) ? " errors " : " error")); - getLog().info("-------------------------------------------------------------"); + if (!errors.isEmpty()) { + getLog().info("-------------------------------------------------------------"); + getLog().error("COMPILATION ERROR : "); + getLog().info("-------------------------------------------------------------"); + for (CompilerMessage error : errors) { + getLog().error(error.toString()); } + getLog().info(errors.size() + ((errors.size() > 1) ? " errors " : " error")); + getLog().info("-------------------------------------------------------------"); + } - if (!errors.isEmpty()) { - throw new CompilationFailureException(errors); - } else { - throw new CompilationFailureException(warnings); - } + if (!errors.isEmpty()) { + throw new CompilationFailureException(errors); } else { - for (CompilerMessage message : compilerResult.getCompilerMessages()) { - switch (message.getKind()) { - case NOTE: - case OTHER: - getLog().info(message.toString()); - break; - - case ERROR: - getLog().error(message.toString()); - break; - - case MANDATORY_WARNING: - case WARNING: - default: - getLog().warn(message.toString()); - break; - } - } + throw new CompilationFailureException(warnings); } - - for (final Artifact artifact : artifacts) { - Zips.unzip(artifact.getFile(), archives); + } else { + for (CompilerMessage message : compilerResult.getCompilerMessages()) { + switch (message.getKind()) { + case NOTE: + case OTHER: + getLog().info(message.toString()); + break; + + case ERROR: + getLog().error(message.toString()); + break; + + case MANDATORY_WARNING: + case WARNING: + default: + getLog().warn(message.toString()); + break; + } } - } catch (IOException e) { - throw new MojoExecutionException("Error occurred during execution", e); } }
