This is an automated email from the ASF dual-hosted git repository. slachiewicz pushed a commit to branch agent/595-include-resource-missing-file in repository https://gitbox.apache.org/repos/asf/maven-shade-plugin.git
commit 3f607da921681958e45303680fdfb2f9a7fad49f Author: Sylwester Lachiewicz <[email protected]> AuthorDate: Tue Oct 27 21:31:14 2026 +0000 [#595] Fail the build when an IncludeResourceTransformer file does not exist The transformer reported nothing to write for a missing file, so a typo in <file> silently dropped the resource from the jar. --- .../invoker.properties | 18 +++++ .../projects/include-resource-missing-file/pom.xml | 73 ++++++++++++++++++++ .../include-resource-missing-file/verify.groovy | 22 ++++++ .../shade/resource/IncludeResourceTransformer.java | 6 +- .../markdown/examples/resource-transformers.md.vm | 2 +- .../resource/IncludeResourceTransformerTest.java | 78 ++++++++++++++++++++++ 6 files changed, 197 insertions(+), 2 deletions(-) diff --git a/src/it/projects/include-resource-missing-file/invoker.properties b/src/it/projects/include-resource-missing-file/invoker.properties new file mode 100644 index 00000000..f2a7dfb4 --- /dev/null +++ b/src/it/projects/include-resource-missing-file/invoker.properties @@ -0,0 +1,18 @@ +# 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. + +invoker.buildResult = failure diff --git a/src/it/projects/include-resource-missing-file/pom.xml b/src/it/projects/include-resource-missing-file/pom.xml new file mode 100644 index 00000000..31d08e55 --- /dev/null +++ b/src/it/projects/include-resource-missing-file/pom.xml @@ -0,0 +1,73 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- +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. +--> + +<project> + <modelVersion>4.0.0</modelVersion> + + <groupId>org.apache.maven.its.shade.irmf</groupId> + <artifactId>test</artifactId> + <version>1.0</version> + <packaging>jar</packaging> + + <name>include-resource-missing-file</name> + <description> + Test that asserts failure if the file of an IncludeResourceTransformer does not exist. + </description> + + <properties> + <slf4j.version>1.7.36</slf4j.version> + </properties> + + <dependencies> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + <version>${slf4j.version}</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-shade-plugin</artifactId> + <version>@project.version@</version> + <executions> + <execution> + <id>attach-shade</id> + <phase>package</phase> + <goals> + <goal>shade</goal> + </goals> + <configuration> + <transformers> + <transformer implementation="org.apache.maven.plugins.shade.resource.IncludeResourceTransformer"> + <resource>META-INF/LICENSE</resource> + <file>no-such-file.txt</file> + </transformer> + </transformers> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> diff --git a/src/it/projects/include-resource-missing-file/verify.groovy b/src/it/projects/include-resource-missing-file/verify.groovy new file mode 100644 index 00000000..c7a9f69a --- /dev/null +++ b/src/it/projects/include-resource-missing-file/verify.groovy @@ -0,0 +1,22 @@ +/* + * 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. + */ + +def buildLog = new File(basedir, 'build.log').text +assert buildLog.contains('no-such-file.txt') +assert buildLog.contains('does not exist or is not a file') diff --git a/src/main/java/org/apache/maven/plugins/shade/resource/IncludeResourceTransformer.java b/src/main/java/org/apache/maven/plugins/shade/resource/IncludeResourceTransformer.java index 330ea4f3..c28b5e42 100644 --- a/src/main/java/org/apache/maven/plugins/shade/resource/IncludeResourceTransformer.java +++ b/src/main/java/org/apache/maven/plugins/shade/resource/IncludeResourceTransformer.java @@ -55,11 +55,15 @@ public class IncludeResourceTransformer extends AbstractCompatibilityTransformer @Override public boolean hasTransformedResource() { - return file != null && file.exists(); + return file != null; } @Override public void modifyOutputStream(JarOutputStream jos) throws IOException { + if (!file.isFile()) { + throw new IOException("IncludeResourceTransformer: file " + file + " for resource " + resource + + " does not exist or is not a file"); + } JarEntry jarEntry = new JarEntry(resource); jarEntry.setTime(time); diff --git a/src/site/markdown/examples/resource-transformers.md.vm b/src/site/markdown/examples/resource-transformers.md.vm index 2ba2b167..e7f315a0 100644 --- a/src/site/markdown/examples/resource-transformers.md.vm +++ b/src/site/markdown/examples/resource-transformers.md.vm @@ -311,7 +311,7 @@ Since maven-shade-plugin-3.0 it is also possible to give a list of resources whi Adding New Resources with the <a id="IncludeResourceTransformer"></a>IncludeResourceTransformer ----------------------------------------------------------------------------------------------- -The `IncludeResourceTransformer` allows project files to be included in the package under a given name. +The `IncludeResourceTransformer` allows project files to be included in the package under a given name. The build fails if the file does not exist. For example, the following sample includes `README.txt` in the package as `README` in the `META-INF` directory. diff --git a/src/test/java/org/apache/maven/plugins/shade/resource/IncludeResourceTransformerTest.java b/src/test/java/org/apache/maven/plugins/shade/resource/IncludeResourceTransformerTest.java new file mode 100644 index 00000000..3e409a3f --- /dev/null +++ b/src/test/java/org/apache/maven/plugins/shade/resource/IncludeResourceTransformerTest.java @@ -0,0 +1,78 @@ +/* + * 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.shade.resource; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.jar.JarInputStream; +import java.util.jar.JarOutputStream; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Test for {@link IncludeResourceTransformer}. + */ +class IncludeResourceTransformerTest { + + @TempDir + Path tempDir; + + @Test + void includesTheFile() throws IOException { + Path file = Files.write(tempDir.resolve("LICENSE"), "license text".getBytes(StandardCharsets.UTF_8)); + IncludeResourceTransformer transformer = new IncludeResourceTransformer(); + transformer.file = file.toFile(); + transformer.resource = "META-INF/LICENSE"; + + assertTrue(transformer.hasTransformedResource()); + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + try (JarOutputStream jos = new JarOutputStream(bytes)) { + transformer.modifyOutputStream(jos); + } + + try (JarInputStream jis = new JarInputStream(new ByteArrayInputStream(bytes.toByteArray()))) { + assertEquals("META-INF/LICENSE", jis.getNextJarEntry().getName()); + } + } + + @Test + void failsWhenTheFileIsMissing() { + File missing = tempDir.resolve("no-such-file").toFile(); + IncludeResourceTransformer transformer = new IncludeResourceTransformer(); + transformer.file = missing; + transformer.resource = "META-INF/LICENSE"; + + assertTrue(transformer.hasTransformedResource(), "a configured file must not be skipped silently"); + IOException e = assertThrows( + IOException.class, + () -> transformer.modifyOutputStream(new JarOutputStream(new ByteArrayOutputStream()))); + assertTrue(e.getMessage().contains(missing.toString()), e.getMessage()); + assertTrue(e.getMessage().contains("META-INF/LICENSE"), e.getMessage()); + } +}
