This is an automated email from the ASF dual-hosted git repository.
michaelo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven-shade-plugin.git
The following commit(s) were added to refs/heads/master by this push:
new 45dcf07 [MSHADE-400] Self-minimisation with custom entry points
45dcf07 is described below
commit 45dcf07f09cd4c896812024898cd1906a74a17f2
Author: Alexander Kriegisch <[email protected]>
AuthorDate: Thu Jul 22 15:06:23 2021 +0700
[MSHADE-400] Self-minimisation with custom entry points
Also add self-minimisation + SPI services IT.
Remove MinijarFilterTest.removeServicesShouldIgnoreDirectories, because
now removing services precisely does **not** ignore directories anymore.
Co-authored-by: Romain Manni-Bucau <[email protected]>
Co-authored-by: Jan Mosig <[email protected]>
This closes #110
---
.../invoker.properties | 1 +
.../MSHADE-313_minimized-services/verify.bsh | 2 +
src/it/projects/MSHADE-316/invoker.properties | 6 +-
.../invoker.properties | 1 +
.../MSHADE-400_self-minimized-services/pom.xml | 60 +++++++
.../src/main/java/org/acme/Application.java | 31 ++++
.../src/main/java/org/acme/UnusedClass.java | 23 +++
.../src/main/java/org/acme/UnusedService.java | 24 +++
.../src/main/java/org/acme/UnusedServiceImplA.java | 27 +++
.../src/main/java/org/acme/UnusedServiceImplB.java | 27 +++
.../src/main/java/org/acme/UsedClass.java | 23 +++
.../src/main/java/org/acme/UsedService.java | 24 +++
.../main/java/org/acme/UsedServiceUnusedImpl.java | 27 +++
.../main/java/org/acme/UsedServiceUsedImpl.java | 27 +++
.../META-INF/services/org.acme.UnusedService} | 6 +-
.../META-INF/services/org.acme.UsedService} | 7 +-
.../verify.bsh | 27 ++-
.../apache/maven/plugins/shade/DefaultShader.java | 188 +++++++++++++++------
.../maven/plugins/shade/filter/MinijarFilter.java | 103 ++++++++++-
.../apache/maven/plugins/shade/mojo/ShadeMojo.java | 51 +++++-
.../maven/plugins/shade/DefaultShaderTest.java | 80 ++++++++-
.../plugins/shade/filter/MinijarFilterTest.java | 22 +--
22 files changed, 671 insertions(+), 116 deletions(-)
diff --git a/src/it/projects/MSHADE-313_minimized-services/invoker.properties
b/src/it/projects/MSHADE-313_minimized-services/invoker.properties
index c8b7b3c..31f873f 100644
--- a/src/it/projects/MSHADE-313_minimized-services/invoker.properties
+++ b/src/it/projects/MSHADE-313_minimized-services/invoker.properties
@@ -15,4 +15,5 @@
# specific language governing permissions and limitations
# under the License.
+# jdependency-2.6.0 needs Java 8+
invoker.java.version = 1.8+
diff --git a/src/it/projects/MSHADE-313_minimized-services/verify.bsh
b/src/it/projects/MSHADE-313_minimized-services/verify.bsh
index 2a58a84..2529359 100644
--- a/src/it/projects/MSHADE-313_minimized-services/verify.bsh
+++ b/src/it/projects/MSHADE-313_minimized-services/verify.bsh
@@ -34,6 +34,8 @@ String[] wanted =
String[] unwanted =
{
+ // Unused SPI config files are not removed
+ //"META-INF/services/UnusedServiceInterface",
"UnusedServiceInterface.class",
"UnusedServiceClass.class",
"SomeUnreferencedClass.class",
diff --git a/src/it/projects/MSHADE-316/invoker.properties
b/src/it/projects/MSHADE-316/invoker.properties
index f1e7ddb..31f873f 100644
--- a/src/it/projects/MSHADE-316/invoker.properties
+++ b/src/it/projects/MSHADE-316/invoker.properties
@@ -5,9 +5,9 @@
# 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
@@ -15,5 +15,5 @@
# specific language governing permissions and limitations
# under the License.
-#jdependency-2.1.1 is Java8 compatible
+# jdependency-2.6.0 needs Java 8+
invoker.java.version = 1.8+
diff --git a/src/it/projects/MSHADE-313_minimized-services/invoker.properties
b/src/it/projects/MSHADE-400_self-minimized-services/invoker.properties
similarity index 95%
copy from src/it/projects/MSHADE-313_minimized-services/invoker.properties
copy to src/it/projects/MSHADE-400_self-minimized-services/invoker.properties
index c8b7b3c..31f873f 100644
--- a/src/it/projects/MSHADE-313_minimized-services/invoker.properties
+++ b/src/it/projects/MSHADE-400_self-minimized-services/invoker.properties
@@ -15,4 +15,5 @@
# specific language governing permissions and limitations
# under the License.
+# jdependency-2.6.0 needs Java 8+
invoker.java.version = 1.8+
diff --git a/src/it/projects/MSHADE-400_self-minimized-services/pom.xml
b/src/it/projects/MSHADE-400_self-minimized-services/pom.xml
new file mode 100644
index 0000000..b48424d
--- /dev/null
+++ b/src/it/projects/MSHADE-400_self-minimized-services/pom.xml
@@ -0,0 +1,60 @@
+<?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 xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.acme</groupId>
+ <artifactId>module-with-services</artifactId>
+ <version>1.0</version>
+
+ <properties>
+ <maven.compiler.source>8</maven.compiler.source>
+ <maven.compiler.target>8</maven.compiler.target>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-shade-plugin</artifactId>
+ <version>@project.version@</version>
+ <executions>
+ <execution>
+ <id>shade</id>
+ <phase>package</phase>
+ <goals>
+ <goal>shade</goal>
+ </goals>
+ <configuration>
+ <minimizeJar>true</minimizeJar>
+ <entryPoints>
+ <entryPoint>org.acme.Application</entryPoint>
+ </entryPoints>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git
a/src/it/projects/MSHADE-400_self-minimized-services/src/main/java/org/acme/Application.java
b/src/it/projects/MSHADE-400_self-minimized-services/src/main/java/org/acme/Application.java
new file mode 100644
index 0000000..1dfaeda
--- /dev/null
+++
b/src/it/projects/MSHADE-400_self-minimized-services/src/main/java/org/acme/Application.java
@@ -0,0 +1,31 @@
+/*
+ * 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.acme;
+
+import java.util.ServiceLoader;
+
+public class Application
+{
+ private UsedClass usedClass = new UsedClass();
+
+ public static void main( String[] args )
+ {
+ ServiceLoader.load( UsedService.class );
+ }
+}
diff --git
a/src/it/projects/MSHADE-400_self-minimized-services/src/main/java/org/acme/UnusedClass.java
b/src/it/projects/MSHADE-400_self-minimized-services/src/main/java/org/acme/UnusedClass.java
new file mode 100644
index 0000000..500782b
--- /dev/null
+++
b/src/it/projects/MSHADE-400_self-minimized-services/src/main/java/org/acme/UnusedClass.java
@@ -0,0 +1,23 @@
+/*
+ * 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.acme;
+
+public class UnusedClass
+{
+}
diff --git
a/src/it/projects/MSHADE-400_self-minimized-services/src/main/java/org/acme/UnusedService.java
b/src/it/projects/MSHADE-400_self-minimized-services/src/main/java/org/acme/UnusedService.java
new file mode 100644
index 0000000..7f6410a
--- /dev/null
+++
b/src/it/projects/MSHADE-400_self-minimized-services/src/main/java/org/acme/UnusedService.java
@@ -0,0 +1,24 @@
+/*
+ * 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.acme;
+
+public interface UnusedService
+{
+ public void doSomething();
+}
diff --git
a/src/it/projects/MSHADE-400_self-minimized-services/src/main/java/org/acme/UnusedServiceImplA.java
b/src/it/projects/MSHADE-400_self-minimized-services/src/main/java/org/acme/UnusedServiceImplA.java
new file mode 100644
index 0000000..0269a72
--- /dev/null
+++
b/src/it/projects/MSHADE-400_self-minimized-services/src/main/java/org/acme/UnusedServiceImplA.java
@@ -0,0 +1,27 @@
+/*
+ * 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.acme;
+
+public class UnusedServiceImplA implements UnusedService
+{
+ @Override
+ public void doSomething()
+ {
+ }
+}
diff --git
a/src/it/projects/MSHADE-400_self-minimized-services/src/main/java/org/acme/UnusedServiceImplB.java
b/src/it/projects/MSHADE-400_self-minimized-services/src/main/java/org/acme/UnusedServiceImplB.java
new file mode 100644
index 0000000..dc1d3d6
--- /dev/null
+++
b/src/it/projects/MSHADE-400_self-minimized-services/src/main/java/org/acme/UnusedServiceImplB.java
@@ -0,0 +1,27 @@
+/*
+ * 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.acme;
+
+public class UnusedServiceImplB implements UnusedService
+{
+ @Override
+ public void doSomething()
+ {
+ }
+}
diff --git
a/src/it/projects/MSHADE-400_self-minimized-services/src/main/java/org/acme/UsedClass.java
b/src/it/projects/MSHADE-400_self-minimized-services/src/main/java/org/acme/UsedClass.java
new file mode 100644
index 0000000..1531521
--- /dev/null
+++
b/src/it/projects/MSHADE-400_self-minimized-services/src/main/java/org/acme/UsedClass.java
@@ -0,0 +1,23 @@
+/*
+ * 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.acme;
+
+public class UsedClass
+{
+}
diff --git
a/src/it/projects/MSHADE-400_self-minimized-services/src/main/java/org/acme/UsedService.java
b/src/it/projects/MSHADE-400_self-minimized-services/src/main/java/org/acme/UsedService.java
new file mode 100644
index 0000000..23c2840
--- /dev/null
+++
b/src/it/projects/MSHADE-400_self-minimized-services/src/main/java/org/acme/UsedService.java
@@ -0,0 +1,24 @@
+/*
+ * 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.acme;
+
+public interface UsedService
+{
+ public void doSomething();
+}
diff --git
a/src/it/projects/MSHADE-400_self-minimized-services/src/main/java/org/acme/UsedServiceUnusedImpl.java
b/src/it/projects/MSHADE-400_self-minimized-services/src/main/java/org/acme/UsedServiceUnusedImpl.java
new file mode 100644
index 0000000..800ddf0
--- /dev/null
+++
b/src/it/projects/MSHADE-400_self-minimized-services/src/main/java/org/acme/UsedServiceUnusedImpl.java
@@ -0,0 +1,27 @@
+/*
+ * 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.acme;
+
+public class UsedServiceUnusedImpl implements UsedService
+{
+ @Override
+ public void doSomething()
+ {
+ }
+}
diff --git
a/src/it/projects/MSHADE-400_self-minimized-services/src/main/java/org/acme/UsedServiceUsedImpl.java
b/src/it/projects/MSHADE-400_self-minimized-services/src/main/java/org/acme/UsedServiceUsedImpl.java
new file mode 100644
index 0000000..345235c
--- /dev/null
+++
b/src/it/projects/MSHADE-400_self-minimized-services/src/main/java/org/acme/UsedServiceUsedImpl.java
@@ -0,0 +1,27 @@
+/*
+ * 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.acme;
+
+public class UsedServiceUsedImpl implements UsedService
+{
+ @Override
+ public void doSomething()
+ {
+ }
+}
diff --git a/src/it/projects/MSHADE-313_minimized-services/invoker.properties
b/src/it/projects/MSHADE-400_self-minimized-services/src/main/resources/META-INF/services/org.acme.UnusedService
similarity index 82%
copy from src/it/projects/MSHADE-313_minimized-services/invoker.properties
copy to
src/it/projects/MSHADE-400_self-minimized-services/src/main/resources/META-INF/services/org.acme.UnusedService
index c8b7b3c..c4f9684 100644
--- a/src/it/projects/MSHADE-313_minimized-services/invoker.properties
+++
b/src/it/projects/MSHADE-400_self-minimized-services/src/main/resources/META-INF/services/org.acme.UnusedService
@@ -1,3 +1,4 @@
+#
# 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
@@ -14,5 +15,8 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
+#
-invoker.java.version = 1.8+
+# These services are defined, but not used in the entry point or any of its
dependency classes
+org.acme.UnusedServiceUsedImplA
+org.acme.UnusedServiceUsedImplB
diff --git a/src/it/projects/MSHADE-313_minimized-services/invoker.properties
b/src/it/projects/MSHADE-400_self-minimized-services/src/main/resources/META-INF/services/org.acme.UsedService
similarity index 88%
copy from src/it/projects/MSHADE-313_minimized-services/invoker.properties
copy to
src/it/projects/MSHADE-400_self-minimized-services/src/main/resources/META-INF/services/org.acme.UsedService
index c8b7b3c..0cf82b0 100644
--- a/src/it/projects/MSHADE-313_minimized-services/invoker.properties
+++
b/src/it/projects/MSHADE-400_self-minimized-services/src/main/resources/META-INF/services/org.acme.UsedService
@@ -1,3 +1,4 @@
+#
# 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
@@ -14,5 +15,9 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
+#
+
+org.acme.UsedServiceUsedImpl
-invoker.java.version = 1.8+
+# This implementation is *not* used:
+# org.acme.UsedServiceUnusedImpl
diff --git a/src/it/projects/MSHADE-313_minimized-services/verify.bsh
b/src/it/projects/MSHADE-400_self-minimized-services/verify.bsh
similarity index 68%
copy from src/it/projects/MSHADE-313_minimized-services/verify.bsh
copy to src/it/projects/MSHADE-400_self-minimized-services/verify.bsh
index 2a58a84..2708621 100644
--- a/src/it/projects/MSHADE-313_minimized-services/verify.bsh
+++ b/src/it/projects/MSHADE-400_self-minimized-services/verify.bsh
@@ -21,26 +21,25 @@ import java.util.jar.*;
String[] wanted =
{
- "Main.class",
- "META-INF/services/SomeServiceInterface",
- "SomeServiceInterface.class",
- "SomeServiceClass.class",
- "SomeReferencedClass.class",
- "META-INF/services/DependencyServiceInterface",
- "DependencyServiceInterface.class",
- "DependencyServiceClass.class",
- "DependencyReferencedClass.class"
+ "META-INF/services/org.acme.UsedService",
+ "org/acme/Application.class",
+ "org/acme/UsedClass.class",
+ "org/acme/UsedService.class",
+ "org/acme/UsedServiceUsedImpl.class"
};
String[] unwanted =
{
- "UnusedServiceInterface.class",
- "UnusedServiceClass.class",
- "SomeUnreferencedClass.class",
- "DependencyUnreferencedClass.class"
+ // Unused SPI config files are not removed
+ //"META-INF/services/org.acme.UnusedService",
+ "org/acme/UsedServiceUnusedImpl.class",
+ "org/acme/UnusedClass.class",
+ "org/acme/UnusedService.class",
+ "org/acme/UnusedServiceImplA.class",
+ "org/acme/UnusedServiceImplB.class"
};
-JarFile jarFile = new JarFile( new File( basedir, "test/target/test-1.0.jar" )
);
+JarFile jarFile = new JarFile( new File( basedir,
"target/module-with-services-1.0.jar" ) );
for ( String path : wanted )
{
diff --git a/src/main/java/org/apache/maven/plugins/shade/DefaultShader.java
b/src/main/java/org/apache/maven/plugins/shade/DefaultShader.java
index b0be384..16f20d9 100644
--- a/src/main/java/org/apache/maven/plugins/shade/DefaultShader.java
+++ b/src/main/java/org/apache/maven/plugins/shade/DefaultShader.java
@@ -22,6 +22,7 @@ package org.apache.maven.plugins.shade;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
+import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -40,6 +41,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.Set;
+import java.util.concurrent.Callable;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
@@ -236,60 +238,142 @@ public class DefaultShader
logger.debug( "Processing JAR " + jar );
List<Filter> jarFilters = getFilters( jar,
shadeRequest.getFilters() );
-
- try ( JarFile jarFile = newJarFile( jar ) )
+ if ( jar.isDirectory() )
+ {
+ shadeDir( shadeRequest, resources, transformers,
packageMapper, jos, duplicates,
+ jar, jar, "", jarFilters );
+ }
+ else
{
+ shadeJar( shadeRequest, resources, transformers,
packageMapper, jos, duplicates,
+ jar, jarFilters );
+ }
+ }
+ }
- for ( Enumeration<JarEntry> j = jarFile.entries();
j.hasMoreElements(); )
+ private void shadeDir( ShadeRequest shadeRequest, Set<String> resources,
+ List<ResourceTransformer> transformers,
DefaultPackageMapper packageMapper,
+ JarOutputStream jos, MultiValuedMap<String, File>
duplicates,
+ File jar, File current, String prefix, List<Filter>
jarFilters ) throws IOException
+ {
+ final File[] children = current.listFiles();
+ if ( children == null )
+ {
+ return;
+ }
+ for ( final File file : children )
+ {
+ final String name = prefix + file.getName();
+ if ( file.isDirectory() )
+ {
+ try
+ {
+ shadeDir(
+ shadeRequest, resources, transformers,
packageMapper, jos,
+ duplicates, jar, file,
+ prefix + file.getName() + '/', jarFilters );
+ continue;
+ }
+ catch ( Exception e )
{
- JarEntry entry = j.nextElement();
+ throw new IOException(
+ String.format( "Problem shading JAR %s entry %s:
%s", current, name, e ), e );
+ }
+ }
+ if ( isFiltered( jarFilters, name ) || isExcludedEntry( name ) )
+ {
+ continue;
+ }
- String name = entry.getName();
-
- if ( entry.isDirectory() || isFiltered( jarFilters, name )
)
- {
- continue;
- }
+ try
+ {
+ shadeJarEntry(
+ shadeRequest, resources, transformers, packageMapper,
jos, duplicates, jar,
+ new Callable<InputStream>()
+ {
+ @Override
+ public InputStream call() throws Exception
+ {
+ return new FileInputStream( file );
+ }
+ }, name, file.lastModified(), -1 /*ignore*/ );
+ }
+ catch ( Exception e )
+ {
+ throw new IOException( String.format( "Problem shading JAR %s
entry %s: %s", current, name, e ),
+ e );
+ }
+ }
+ }
+ private void shadeJar( ShadeRequest shadeRequest, Set<String> resources,
+ List<ResourceTransformer> transformers,
DefaultPackageMapper packageMapper,
+ JarOutputStream jos, MultiValuedMap<String, File>
duplicates,
+ File jar, List<Filter> jarFilters ) throws
IOException
+ {
+ try ( JarFile jarFile = newJarFile( jar ) )
+ {
- if ( "META-INF/INDEX.LIST".equals( name ) )
- {
- // we cannot allow the jar indexes to be copied over
or the
- // jar is useless. Ideally, we could create a new one
- // later
- continue;
- }
+ for ( Enumeration<JarEntry> j = jarFile.entries();
j.hasMoreElements(); )
+ {
+ final JarEntry entry = j.nextElement();
- if ( "module-info.class".equals( name ) )
- {
- logger.warn( "Discovered module-info.class. "
- + "Shading will break its strong encapsulation." );
- continue;
- }
+ String name = entry.getName();
- try
- {
- shadeJarEntry( shadeRequest, resources, transformers,
packageMapper, jos, duplicates, jar,
- jarFile, entry, name );
- }
- catch ( Exception e )
- {
- throw new IOException( String.format( "Problem shading
JAR %s entry %s: %s", jar, name, e ),
- e );
- }
+ if ( entry.isDirectory() || isFiltered( jarFilters, name ) ||
isExcludedEntry( name ) )
+ {
+ continue;
}
+ try
+ {
+ shadeJarEntry(
+ shadeRequest, resources, transformers,
packageMapper, jos, duplicates, jar,
+ new Callable<InputStream>()
+ {
+ @Override
+ public InputStream call() throws Exception
+ {
+ return jarFile.getInputStream( entry );
+ }
+ }, name, entry.getTime(), entry.getMethod() );
+ }
+ catch ( Exception e )
+ {
+ throw new IOException( String.format( "Problem shading JAR
%s entry %s: %s", jar, name, e ),
+ e );
+ }
}
+
}
}
+ private boolean isExcludedEntry( final String name )
+ {
+ if ( "META-INF/INDEX.LIST".equals( name ) )
+ {
+ // we cannot allow the jar indexes to be copied over or the
+ // jar is useless. Ideally, we could create a new one
+ // later
+ return true;
+ }
+
+ if ( "module-info.class".equals( name ) )
+ {
+ logger.warn( "Discovered module-info.class. "
+ + "Shading will break its strong encapsulation." );
+ return true;
+ }
+ return false;
+ }
+
private void shadeJarEntry( ShadeRequest shadeRequest, Set<String>
resources,
List<ResourceTransformer> transformers,
DefaultPackageMapper packageMapper,
JarOutputStream jos, MultiValuedMap<String,
File> duplicates, File jar,
- JarFile jarFile, JarEntry entry, String name )
- throws IOException, MojoExecutionException
+ Callable<InputStream> inputProvider, String
name, long time, int method )
+ throws Exception
{
- try ( InputStream in = jarFile.getInputStream( entry ) )
+ try ( InputStream in = inputProvider.call() )
{
String mappedName = packageMapper.map( name, true, false );
@@ -300,14 +384,14 @@ public class DefaultShader
String dir = mappedName.substring( 0, idx );
if ( !resources.contains( dir ) )
{
- addDirectory( resources, jos, dir, entry.getTime() );
+ addDirectory( resources, jos, dir, time );
}
}
duplicates.put( name, jar );
if ( name.endsWith( ".class" ) )
{
- addRemappedClass( jos, jar, name, entry.getTime(), in,
packageMapper );
+ addRemappedClass( jos, jar, name, time, in, packageMapper );
}
else if ( shadeRequest.isShadeSourcesContent() && name.endsWith(
".java" ) )
{
@@ -317,12 +401,12 @@ public class DefaultShader
return;
}
- addJavaSource( resources, jos, mappedName, entry.getTime(),
in, shadeRequest.getRelocators() );
+ addJavaSource( resources, jos, mappedName, time, in,
shadeRequest.getRelocators() );
}
else
{
if ( !resourceTransformed( transformers, mappedName, in,
shadeRequest.getRelocators(),
- entry.getTime() ) )
+ time ) )
{
// Avoid duplicates that aren't accounted for by the
resource transformers
if ( resources.contains( mappedName ) )
@@ -331,7 +415,7 @@ public class DefaultShader
return;
}
- addResource( resources, jos, mappedName, entry, jarFile );
+ addResource( resources, jos, mappedName, inputProvider,
time, method );
}
else
{
@@ -537,12 +621,12 @@ public class DefaultShader
return;
}
-
- // Keep the original class in, in case nothing was relocated by
RelocatorRemapper. This avoids binary
+
+ // Keep the original class, in case nothing was relocated by
ShadeClassRemapper. This avoids binary
// differences between classes, simply because they were rewritten and
only details like constant pool or
// stack map frames are slightly different.
byte[] originalClass = IOUtil.toByteArray( is );
-
+
ClassReader cr = new ClassReader( new ByteArrayInputStream(
originalClass ) );
// We don't pass the ClassReader here. This forces the ClassWriter to
rebuild the constant pool.
@@ -564,7 +648,7 @@ public class DefaultShader
throw new MojoExecutionException( "Error in ASM processing class "
+ name, ise );
}
- // If nothing was relocated by RelocatorRemapper, write the original
class, otherwise the transformed one
+ // If nothing was relocated by ShadeClassRemapper, write the original
class, otherwise the transformed one
final byte[] renamedClass;
if ( cv.remapped )
{
@@ -659,24 +743,24 @@ public class DefaultShader
resources.add( name );
}
- private void addResource( Set<String> resources, JarOutputStream jos,
String name, JarEntry originalEntry,
- JarFile jarFile ) throws IOException
+ private void addResource( Set<String> resources, JarOutputStream jos,
String name, Callable<InputStream> input,
+ long time, int method ) throws Exception
{
- ZipHeaderPeekInputStream inputStream = new ZipHeaderPeekInputStream(
jarFile.getInputStream( originalEntry ) );
+ ZipHeaderPeekInputStream inputStream = new ZipHeaderPeekInputStream(
input.call() );
try
{
final JarEntry entry = new JarEntry( name );
// We should not change compressed level of uncompressed entries,
otherwise JVM can't load these nested jars
- if ( inputStream.hasZipHeader() && originalEntry.getMethod() ==
ZipEntry.STORED )
+ if ( inputStream.hasZipHeader() && method == ZipEntry.STORED )
{
new CrcAndSize( inputStream ).setupStoredEntry( entry );
inputStream.close();
- inputStream = new ZipHeaderPeekInputStream(
jarFile.getInputStream( originalEntry ) );
+ inputStream = new ZipHeaderPeekInputStream( input.call() );
}
- entry.setTime( originalEntry.getTime() );
+ entry.setTime( time );
jos.putNextEntry( entry );
@@ -694,7 +778,7 @@ public class DefaultShader
{
/**
* Map an entity name according to the mapping rules known to this
package mapper
- *
+ *
* @param entityName entity name to be mapped
* @param mapPaths map "slashy" names like paths or internal Java
class names, e.g. {@code com/acme/Foo}?
* @param mapPackages map "dotty" names like qualified Java class or
package names, e.g. {@code com.acme.Foo}?
diff --git
a/src/main/java/org/apache/maven/plugins/shade/filter/MinijarFilter.java
b/src/main/java/org/apache/maven/plugins/shade/filter/MinijarFilter.java
index a996bd4..0ce1c87 100644
--- a/src/main/java/org/apache/maven/plugins/shade/filter/MinijarFilter.java
+++ b/src/main/java/org/apache/maven/plugins/shade/filter/MinijarFilter.java
@@ -77,17 +77,30 @@ public class MinijarFilter
public MinijarFilter( MavenProject project, Log log )
throws IOException
{
- this( project, log, Collections.<SimpleFilter>emptyList() );
+ this( project, log, Collections.<SimpleFilter>emptyList(),
Collections.<String>emptySet() );
+ }
+
+ /**
+ * @param project {@link MavenProject}
+ * @param log {@link Log}
+ * @param entryPoints
+ * @throws IOException in case of error.
+ */
+ public MinijarFilter( MavenProject project, Log log, Set<String>
entryPoints )
+ throws IOException
+ {
+ this( project, log, Collections.<SimpleFilter>emptyList(), entryPoints
);
}
/**
* @param project {@link MavenProject}
* @param log {@link Log}
* @param simpleFilters {@link SimpleFilter}
+ * @param entryPoints
* @throws IOException in case of errors.
* @since 1.6
*/
- public MinijarFilter( MavenProject project, Log log, List<SimpleFilter>
simpleFilters )
+ public MinijarFilter( MavenProject project, Log log, List<SimpleFilter>
simpleFilters, Set<String> entryPoints )
throws IOException
{
this.log = log;
@@ -111,8 +124,44 @@ public class MinijarFilter
log.warn( "Removing module-info from " +
artifactFile.getName() );
}
removePackages( artifactUnit );
- removable.removeAll( artifactUnit.getClazzes() );
- removable.removeAll( artifactUnit.getTransitiveDependencies() );
+ if ( entryPoints.isEmpty() )
+ {
+ removable.removeAll( artifactUnit.getClazzes() );
+ removable.removeAll( artifactUnit.getTransitiveDependencies()
);
+ }
+ else
+ {
+ Set<Clazz> artifactUnitClazzes = artifactUnit.getClazzes();
+ Set<Clazz> entryPointsToKeep = new HashSet<>();
+ for ( String entryPoint : entryPoints )
+ {
+ Clazz entryPointFound = null;
+ for ( Clazz clazz : artifactUnitClazzes )
+ {
+ if ( clazz.getName().equals( entryPoint ) )
+ {
+ entryPointFound = clazz;
+ break;
+ }
+ }
+ if ( entryPointFound != null )
+ {
+ entryPointsToKeep.add( entryPointFound );
+ }
+ }
+ removable.removeAll( entryPointsToKeep );
+ if ( entryPointsToKeep.isEmpty() )
+ {
+ removable.removeAll(
artifactUnit.getTransitiveDependencies() );
+ }
+ else
+ {
+ for ( Clazz entryPoint : entryPointsToKeep )
+ {
+ removable.removeAll(
entryPoint.getTransitiveDependencies() );
+ }
+ }
+ }
removeSpecificallyIncludedClasses( project,
simpleFilters == null ? Collections.<SimpleFilter>emptyList()
: simpleFilters );
removeServices( project, cp );
@@ -137,14 +186,13 @@ public class MinijarFilter
// minification process.
for ( final String fileName :
project.getRuntimeClasspathElements() )
{
- // Ignore the build directory from this project
- if ( fileName.equals(
project.getBuild().getOutputDirectory() ) )
+ if ( new File( fileName ).isDirectory() )
{
- continue;
+ repeatScan |= removeServicesFromDir( cp,
neededClasses, fileName );
}
- if ( removeServicesFromJar( cp, neededClasses, fileName ) )
+ else
{
- repeatScan = true;
+ repeatScan |= removeServicesFromJar( cp,
neededClasses, fileName );
}
}
}
@@ -156,6 +204,43 @@ public class MinijarFilter
while ( repeatScan );
}
+ private boolean removeServicesFromDir( Clazzpath cp, Set<Clazz>
neededClasses, String fileName )
+ {
+ final File servicesDir = new File( fileName, "META-INF/services/" );
+ if ( !servicesDir.isDirectory() )
+ {
+ return false;
+ }
+ final File[] serviceProviderConfigFiles = servicesDir.listFiles();
+ if ( serviceProviderConfigFiles == null ||
serviceProviderConfigFiles.length == 0 )
+ {
+ return false;
+ }
+
+ boolean repeatScan = false;
+ for ( File serviceProviderConfigFile : serviceProviderConfigFiles )
+ {
+ final String serviceClassName =
serviceProviderConfigFile.getName();
+ final boolean isNeededClass = neededClasses.contains( cp.getClazz(
serviceClassName ) );
+ if ( !isNeededClass )
+ {
+ continue;
+ }
+
+ try ( final BufferedReader configFileReader = new BufferedReader(
+ new InputStreamReader( new FileInputStream(
serviceProviderConfigFile ), UTF_8 ) ) )
+ {
+ // check whether the found classes use services in turn
+ repeatScan |= scanServiceProviderConfigFile( cp,
configFileReader );
+ }
+ catch ( final IOException e )
+ {
+ log.warn( e.getMessage() );
+ }
+ }
+ return repeatScan;
+ }
+
private boolean removeServicesFromJar( Clazzpath cp, Set<Clazz>
neededClasses, String fileName )
{
boolean repeatScan = false;
diff --git a/src/main/java/org/apache/maven/plugins/shade/mojo/ShadeMojo.java
b/src/main/java/org/apache/maven/plugins/shade/mojo/ShadeMojo.java
index 40f712c..c83d27c 100644
--- a/src/main/java/org/apache/maven/plugins/shade/mojo/ShadeMojo.java
+++ b/src/main/java/org/apache/maven/plugins/shade/mojo/ShadeMojo.java
@@ -111,7 +111,7 @@ public class ShadeMojo
* syntax <code>groupId</code> is equivalent to
<code>groupId:*:*:*</code>, <code>groupId:artifactId</code> is
* equivalent to <code>groupId:artifactId:*:*</code> and
<code>groupId:artifactId:classifier</code> is equivalent to
* <code>groupId:artifactId:*:classifier</code>. For example:
- *
+ *
* <pre>
* <artifactSet>
* <includes>
@@ -128,7 +128,7 @@ public class ShadeMojo
/**
* Packages to be relocated. For example:
- *
+ *
* <pre>
* <relocations>
* <relocation>
@@ -143,7 +143,7 @@ public class ShadeMojo
* </relocation>
* </relocations>
* </pre>
- *
+ *
* <em>Note:</em> Support for includes exists only since version 1.4.
*/
@SuppressWarnings( "MismatchedReadAndWriteOfArray" )
@@ -164,7 +164,7 @@ public class ShadeMojo
* to use an include to collect a set of files from the archive then use
excludes to further reduce the set. By
* default, all files are included and no files are excluded. If multiple
filters apply to an artifact, the
* intersection of the matched files will be included in the final JAR.
For example:
- *
+ *
* <pre>
* <filters>
* <filter>
@@ -310,13 +310,41 @@ public class ShadeMojo
/**
* When true, dependencies will be stripped down on the class level to
only the transitive hull required for the
- * artifact. <em>Note:</em> Usage of this feature requires Java 1.5 or
higher.
+ * artifact. See also {@link #entryPoints}, if you wish to further
optimize JAR minimization.
+ * <p>
+ * <em>Note:</em> This feature requires Java 1.8 or higher due to its use
of
+ * <a href="https://github.com/tcurdt/jdependency">jdependency</a>. Its
accuracy therefore also depends on
+ * jdependency's limitations.
*
* @since 1.4
*/
@Parameter
private boolean minimizeJar;
+ /**
+ * Use this option in order to fine-tune {@link #minimizeJar}: By default,
all of the target module's classes are
+ * kept and used as entry points for JAR minimization. By explicitly
limiting the set of entry points, you can
+ * further minimize the set of classes kept in the shaded JAR. This
affects both classes in the module itself and
+ * dependency classes. If {@link #minimizeJar} is inactive, this option
has no effect either.
+ * <p>
+ * <em>Note:</em> This feature requires Java 1.8 or higher due to its use
of
+ * <a href="https://github.com/tcurdt/jdependency">jdependency</a>. Its
accuracy therefore also depends on
+ * jdependency's limitations.
+ * <p>
+ * Configuration example:
+ * <pre>{@code
+ * <minimizeJar>true</minimizeJar>
+ * <entryPoints>
+ * <entryPoint>org.acme.Application</entryPoint>
+ * <entryPoint>org.acme.OtherEntryPoint</entryPoint>
+ * </entryPoints>
+ * }</pre>
+ *
+ * @since 3.5.0
+ */
+ @Parameter
+ private Set<String> entryPoints;
+
/**
* The path to the output file for the shaded artifact. When this
parameter is set, the created archive will neither
* replace the project's main artifact nor will it be attached. Hence,
this parameter causes the parameters
@@ -551,7 +579,7 @@ public class ShadeMojo
replaceFile( finalFile, testSourcesJar );
testSourcesJar = finalFile;
}
-
+
renamed = true;
}
@@ -964,11 +992,16 @@ public class ShadeMojo
if ( minimizeJar )
{
- getLog().info( "Minimizing jar " + project.getArtifact() );
+ if ( entryPoints == null )
+ {
+ entryPoints = new HashSet<>();
+ }
+ getLog().info( "Minimizing jar " + project.getArtifact()
+ + ( entryPoints.isEmpty() ? "" : " with entry points" ) );
try
{
- filters.add( new MinijarFilter( project, getLog(),
simpleFilters ) );
+ filters.add( new MinijarFilter( project, getLog(),
simpleFilters, entryPoints ) );
}
catch ( IOException e )
{
@@ -1153,7 +1186,7 @@ public class ShadeMojo
}
File f = dependencyReducedPomLocation;
- // MSHADE-225
+ // MSHADE-225
// Works for now, maybe there's a better algorithm where no
for-loop is required
if ( loopCounter == 0 )
{
diff --git
a/src/test/java/org/apache/maven/plugins/shade/DefaultShaderTest.java
b/src/test/java/org/apache/maven/plugins/shade/DefaultShaderTest.java
index 14786ec..960cf8d 100644
--- a/src/test/java/org/apache/maven/plugins/shade/DefaultShaderTest.java
+++ b/src/test/java/org/apache/maven/plugins/shade/DefaultShaderTest.java
@@ -25,6 +25,7 @@ import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.OutputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.net.URL;
@@ -36,11 +37,13 @@ import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.Enumeration;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
+import java.util.jar.JarInputStream;
import java.util.jar.JarOutputStream;
import java.util.stream.Collectors;
import java.util.zip.CRC32;
@@ -57,6 +60,7 @@ import
org.apache.maven.plugins.shade.resource.ServicesResourceTransformer;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.Os;
import org.junit.Assert;
+import org.junit.ClassRule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.mockito.ArgumentCaptor;
@@ -65,6 +69,9 @@ import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Opcodes;
import org.slf4j.Logger;
+import static java.util.Arrays.asList;
+import static java.util.Collections.singleton;
+import static org.codehaus.plexus.util.FileUtils.forceMkdir;
import static java.util.Objects.requireNonNull;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.hasItem;
@@ -87,6 +94,9 @@ public class DefaultShaderTest
private static final String[] EXCLUDES = new String[] {
"org/codehaus/plexus/util/xml/Xpp3Dom",
"org/codehaus/plexus/util/xml/pull.*" };
+ @ClassRule
+ public static final TemporaryFolder tmp = new TemporaryFolder();
+
private final String NEWLINE = "\n";
@Test
@@ -119,7 +129,7 @@ public class DefaultShaderTest
// Before MSHADE-391, the processed files were written to the uber
JAR, which did no harm, but made it
// difficult to find out by simple file comparison, if a file was
actually relocated or not. Now, Shade
// makes sure to always write the original file if the class
neither was relocated itself nor references
- // other, relocated classes. So we are checking for regressions
here.
+ // other, relocated classes. So we are checking for regressions
here.
assertTrue( areEqual( originalJar, shadedJar,
"org/codehaus/plexus/util/Expand.class" ) );
@@ -289,6 +299,60 @@ public class DefaultShaderTest
new String[] {} );
}
+ @Test
+ public void testHandleDirectory()
+ throws Exception
+ {
+ final File dir = tmp.getRoot();
+ // explode src/test/jars/test-artifact-1.0-SNAPSHOT.jar in this temp
dir
+ try ( final JarInputStream in = new JarInputStream(
+ new FileInputStream(
"src/test/jars/test-artifact-1.0-SNAPSHOT.jar" ) ) )
+ {
+ JarEntry nextJarEntry;
+ while ( (nextJarEntry = in.getNextJarEntry()) != null )
+ {
+ if ( nextJarEntry.isDirectory() )
+ {
+ continue;
+ }
+ final File out = new File( dir, nextJarEntry.getName() );
+ forceMkdir( out.getParentFile() );
+ try ( final OutputStream outputStream = new FileOutputStream(
out ) )
+ {
+ IOUtil.copy( in, outputStream, (int) Math.max(
nextJarEntry.getSize(), 512 ) );
+ }
+ }
+ }
+
+ // do shade
+ final File shade = new File( "target/testHandleDirectory.jar" );
+ shaderWithPattern( "org/shaded/plexus/util", shade, new String[0],
singleton( dir ) );
+
+ // ensure directory was shaded properly
+ try ( final JarFile jar = new JarFile( shade ) )
+ {
+ final List<String> entries = new ArrayList<>();
+ final Enumeration<JarEntry> jarEntryEnumeration = jar.entries();
+ while ( jarEntryEnumeration.hasMoreElements() )
+ {
+ final JarEntry jarEntry = jarEntryEnumeration.nextElement();
+ if ( jarEntry.isDirectory() )
+ {
+ continue;
+ }
+ entries.add( jarEntry.getName() );
+ }
+ Collections.sort( entries );
+ assertEquals(
+ asList(
+
"META-INF/maven/org.apache.maven.plugins.shade/test-artifact/pom.properties",
+
"META-INF/maven/org.apache.maven.plugins.shade/test-artifact/pom.xml",
+ "org/apache/maven/plugins/shade/Lib.class"
+ ),
+ entries );
+ }
+ }
+
@Test
public void testShaderWithRelocatedClassname()
throws Exception
@@ -531,16 +595,18 @@ public class DefaultShaderTest
jos.closeEntry();
}
- private void shaderWithPattern( String shadedPattern, File jar, String[]
excludes )
- throws Exception
+ private void shaderWithPattern( String shadedPattern, File jar, String[]
excludes ) throws Exception
{
- DefaultShader s = newShader();
-
Set<File> set = new LinkedHashSet<>();
-
set.add( new File( "src/test/jars/test-project-1.0-SNAPSHOT.jar" ) );
-
set.add( new File( "src/test/jars/plexus-utils-1.4.1.jar" ) );
+ shaderWithPattern( shadedPattern, jar, excludes, set );
+ }
+
+ private void shaderWithPattern( String shadedPattern, File jar, String[]
excludes, Set<File> set )
+ throws Exception
+ {
+ DefaultShader s = newShader();
List<Relocator> relocators = new ArrayList<>();
diff --git
a/src/test/java/org/apache/maven/plugins/shade/filter/MinijarFilterTest.java
b/src/test/java/org/apache/maven/plugins/shade/filter/MinijarFilterTest.java
index 25be4d8..9f13a12 100644
--- a/src/test/java/org/apache/maven/plugins/shade/filter/MinijarFilterTest.java
+++ b/src/test/java/org/apache/maven/plugins/shade/filter/MinijarFilterTest.java
@@ -32,6 +32,7 @@ import static org.mockito.Mockito.when;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -70,7 +71,7 @@ public class MinijarFilterTest
this.outputDirectory = tempFolder.newFolder();
this.emptyFile = tempFolder.newFile();
this.jarFile = tempFolder.newFile();
- new JarOutputStream( new FileOutputStream( this.jarFile ) ).close();
+ new
JarOutputStream(Files.newOutputStream(this.jarFile.toPath())).close();
this.log = mock(Log.class);
logCaptor = ArgumentCaptor.forClass(CharSequence.class);
}
@@ -187,23 +188,4 @@ public class MinijarFilterTest
}
- /**
- * Verify that directories are ignored when scanning the classpath for
JARs containing services,
- * but warnings are logged instead
- *
- * @see <a
href="https://issues.apache.org/jira/browse/MSHADE-366">MSHADE-366</a>
- */
- @Test
- public void removeServicesShouldIgnoreDirectories() throws Exception {
- String classPathElementToIgnore =
tempFolder.newFolder().getAbsolutePath();
- MavenProject mockedProject = mockProject( outputDirectory, jarFile,
classPathElementToIgnore );
-
- new MinijarFilter(mockedProject, log);
-
- verify( log, times( 1 ) ).warn( logCaptor.capture() );
-
- assertThat( logCaptor.getValue().toString(), startsWith(
- "Not a JAR file candidate. Ignoring classpath element '" +
classPathElementToIgnore + "' (" ) );
- }
-
}