desruisseaux commented on code in PR #508:
URL: https://github.com/apache/maven-jar-plugin/pull/508#discussion_r3949329116


##########
src/main/java/org/apache/maven/plugins/jar/ToolExecutor.java:
##########
@@ -0,0 +1,551 @@
+/*
+ * 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.maven.plugins.jar;
+
+import javax.lang.model.SourceVersion;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+import java.util.spi.ToolProvider;
+
+import org.apache.maven.api.Project;
+import org.apache.maven.api.Type;
+import org.apache.maven.api.plugin.Log;
+import org.apache.maven.api.plugin.MojoException;
+import org.apache.maven.shared.archiver.MavenArchiveConfiguration;
+
+/**
+ * Writer of <abbr>JAR</abbr> files using the information collected by {@link 
FileCollector}.
+ * This class uses the {@code "jar"} tool provided with the <abbr>JDK</abbr>.
+ */
+final class ToolExecutor {
+    /**
+     * First JDK feature version whose {@code jar} tool can run {@code 
--validate} on archives
+     * that contain records. Earlier {@code jar} tools failed with "This 
feature requires ASM8"
+     * (JDK-8282446, fixed by JDK-8282508 in JDK 19 by not backported to a 17u 
or 18u update).
+     *
+     * @see <a 
href="https://bugs.openjdk.org/browse/JDK-8282446";>JDK-8282446</a>
+     * @see <a 
href="https://bugs.openjdk.org/browse/JDK-8282508";>JDK-8282508</a>
+     */
+    private static final int JDK_FIXING_JAR_VALIDATE = 19;
+
+    /**
+     * First JDK feature version whose {@code jar} tool support the {@code 
--date} option.
+     */
+    private static final int JDK_SUPPORT_DATE = 19;
+
+    /**
+     * The {@value} attribute. Its value is automatically generated by {@link 
Manifest},
+     * but may need to be replaced by another value if JDK-independent value 
is desired
+     * for strictly reproducible builds.
+     */
+    private static final String CREATED_BY = "Created-By";
+
+    /**
+     * The Maven project for which to create an archive.
+     */
+    final Project project;
+
+    /**
+     * {@code "jar"} or {@link "test-jar"}.
+     */
+    private final String artifactType;
+
+    /**
+     * The output directory where to write the <abbr>JAR</abbr> file.
+     * This is usually {@code ${baseDir}/target/}.
+     */
+    private final Path outputDirectory;
+
+    /**
+     * The <abbr>JAR</abbr> file name when package hierarchy is used.
+     * This is usually a file placed in the {@link 
ToolExecutor#outputDirectory} directory.
+     */
+    private final String finalName;
+
+    /**
+     * The classifier (e.g. "test"), or {@code null} if none.
+     */
+    private final String classifier;
+
+    /**
+     * Whether to validate the <abbr>JAR</abbr> file after its creation.
+     * If {@code null}, a value will be determined automatically based on 
heuristic rules.
+     */
+    private final Boolean validate;
+
+    /**
+     * The tool to use for creating the <abbr>JAR</abbr> files.
+     */
+    private final ToolProvider tool;
+
+    /**
+     * Where to send messages emitted by the "jar" tool.
+     */
+    private final PrintWriter messageWriter;
+
+    /**
+     * Where to send error messages emitted by the "jar" tool.
+     */
+    private final PrintWriter errorWriter;
+
+    /**
+     * Where the messages sent to {@link #messageWriter} are stored.
+     */
+    private final StringBuffer messages;
+
+    /**
+     * Where the messages sent to {@link #errorWriter} are stored.
+     */
+    private final StringBuffer errors;
+
+    /**
+     * A buffer for the arguments given to the "jar" tool, reused for each 
module.
+     * Each element of the list must be instances of either {@link String} or 
{@link Path}.
+     */
+    private final List<Object> arguments;
+
+    /**
+     * The paths to the created archive files.
+     * Map keys are module names or {@code null} if the project does not use 
module hierarchy.
+     * Values are (<var>type</var>, <var>path</var>) pairs associated with 
each module where
+     * <var>type</var> is {@code "pom"}, {@code "jar"} or {@code "test-jar"} 
and <var>path</var>
+     * is the path to the <abbr>POM</abbr> or <abbr>JAR</abbr> file.
+     */
+    private final Map<String, Map<String, Path>> result;
+
+    /**
+     * Mapper from Maven dependencies to Java modules, or {@code null} if the 
project does not use module hierarchy.
+     * This mapper is created only once for a Maven project and reused for 
each Java module to archive.
+     *
+     * <p>This field is not used directly by {@code ToolExecutor}. It is 
defined in this class for transferring
+     * this information from {@link AbstractJarMojo} to {@link 
PomDerivation.ForModule}.
+     * This is an internal mechanism that should not be public or 
protected.</p>
+     */
+    PomDerivation pomDerivation;
+
+    /**
+     * Manifest to merge with the manifest found in the files to archive.
+     * This is a manifest built from the {@code <archive>} plugin 
configuration.
+     * Can be {@code null} if there is noting to add to the existing manifests.
+     */
+    private final Manifest manifestFromPlugin;
+
+    /**
+     * The file from which {@link #manifestFromPlugin} has been read, or 
{@code null} if none.
+     * If non-null, reading that file must produce the same manifest as {@link 
#manifestFromPlugin}.
+     * It implies that this field must be {@code null} if {@link 
#manifestFromPlugin} is the result
+     * of merging elements specified in {@code <archive>} with a file 
specified in the plugin configuration.
+     */
+    private final Path manifestFile;
+
+    /**
+     * The archive configuration to use.
+     */
+    private final MavenArchiveConfiguration archiveConfiguration;
+
+    /**
+     * The timestamp in ISO-8601 extended offset date-time, or {@code null} if 
none.
+     * If user provided a value in seconds, it must have been converted to 
ISO-8601.
+     * This is used for reproducible builds.
+     */
+    private final String outputTimestamp;
+
+    /**
+     * Whether to force to build new <abbr>JAR</abbr> files even if none of 
the contents appear to have changed.
+     */
+    private final boolean forceCreation;
+
+    /**
+     * Where to send informative or error messages.
+     */
+    private final Log logger;
+
+    /**
+     * Creates a new writer.
+     *
+     * @param mojo the <abbr>MOJO</abbr> from which to get the configuration
+     * @param manifest manifest built from plugin configuration, or {@code 
null} if none
+     * @param archive the archive configuration
+     * @throws IOException if an error occurred while reading the manifest file
+     */
+    ToolExecutor(AbstractJarMojo mojo, Manifest manifest, 
MavenArchiveConfiguration archive) throws IOException {
+        project = mojo.project;
+        artifactType = mojo.getType();
+        outputDirectory = mojo.getOutputDirectory();
+        classifier = AbstractJarMojo.nullIfAbsent(mojo.getClassifier());
+        finalName =
+                (mojo.finalName != null) ? mojo.finalName : 
project.getBuild().getFinalName();
+        forceCreation = mojo.forceCreation;
+        outputTimestamp = mojo.getOutputTimestamp();
+        validate = mojo.getValidate();
+        logger = mojo.log;
+        tool = mojo.getJarTool();
+
+        var buffer = new StringWriter();
+        messages = buffer.getBuffer();
+        messageWriter = new PrintWriter(buffer);
+
+        buffer = new StringWriter();
+        errors = buffer.getBuffer();
+        errorWriter = new PrintWriter(buffer);

Review Comment:
   `java.util.spi.ToolProvider` knows nothing about Maven loggers. 
`errorWriter` is where the tool reports the errors. Then, if `errorWriter` is 
non empty, the Maven JAR Plugin copies its content to the Maven logger.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to