From cda0b49aeab69a6960281705a8337f9817ca7474 Mon Sep 17 00:00:00 2001 From: Niels Basjes Date: Sun, 5 Nov 2023 11:41:16 +0100 Subject: [PATCH] [MSHADE-406] Support for Multi Release Jars (JEP-238) --- .github/workflows/maven-verify.yml | 6 +- .gitignore | 3 +- pom.xml | 13 +- .../invoker.properties | 22 ++ .../pom.xml | 287 ++++++++++++++++++ .../src/main/java/nl/example/Main.java | 31 ++ .../verify.groovy | 79 +++++ .../invoker.properties | 22 ++ .../MultiReleaseJar-shade-minimize/pom.xml | 287 ++++++++++++++++++ .../src/main/java/nl/example/Main.java | 31 ++ .../verify.groovy | 60 ++++ .../invoker.properties | 22 ++ .../MultiReleaseJar-shade-relocate/pom.xml | 287 ++++++++++++++++++ .../src/main/java/nl/example/Main.java | 31 ++ .../verify.groovy | 79 +++++ .../MultiReleaseJar-shade/invoker.properties | 22 ++ src/it/projects/MultiReleaseJar-shade/pom.xml | 287 ++++++++++++++++++ .../src/main/java/nl/example/Main.java | 31 ++ .../MultiReleaseJar-shade/verify.groovy | 61 ++++ .../setup/multiReleaseJar/invoker.properties | 19 ++ src/it/setup/multiReleaseJar/pom.xml | 96 ++++++ .../maven/multijdk/AbstractJavaVersion.java | 35 +++ .../java/nl/basjes/maven/multijdk/App.java | 25 ++ .../nl/basjes/maven/multijdk/JavaVersion.java | 29 ++ .../java/nl/basjes/maven/multijdk/Main.java | 29 ++ .../java/nl/basjes/maven/multijdk/Unused.java | 25 ++ .../java11/nl/basjes/maven/multijdk/App.java | 25 ++ .../nl/basjes/maven/multijdk/JavaVersion.java | 36 +++ .../maven/multijdk/OnlyUsedInJava17.java | 25 ++ .../maven/multijdk/SpecificToJava11.java | 25 ++ .../nl/basjes/maven/multijdk/Unused.java | 25 ++ .../java17/nl/basjes/maven/multijdk/App.java | 25 ++ .../maven/multijdk/SpecificToJava17.java | 25 ++ .../nl/basjes/maven/multijdk/Unused.java | 24 ++ .../maven/plugins/shade/DefaultShader.java | 28 +- .../plugins/shade/filter/MinijarFilter.java | 12 +- .../shade/relocation/SimpleRelocator.java | 6 +- .../resource/ManifestResourceTransformer.java | 7 + 38 files changed, 2165 insertions(+), 17 deletions(-) create mode 100644 src/it/projects/MultiReleaseJar-shade-minimize-relocate/invoker.properties create mode 100644 src/it/projects/MultiReleaseJar-shade-minimize-relocate/pom.xml create mode 100644 src/it/projects/MultiReleaseJar-shade-minimize-relocate/src/main/java/nl/example/Main.java create mode 100644 src/it/projects/MultiReleaseJar-shade-minimize-relocate/verify.groovy create mode 100644 src/it/projects/MultiReleaseJar-shade-minimize/invoker.properties create mode 100644 src/it/projects/MultiReleaseJar-shade-minimize/pom.xml create mode 100644 src/it/projects/MultiReleaseJar-shade-minimize/src/main/java/nl/example/Main.java create mode 100644 src/it/projects/MultiReleaseJar-shade-minimize/verify.groovy create mode 100644 src/it/projects/MultiReleaseJar-shade-relocate/invoker.properties create mode 100644 src/it/projects/MultiReleaseJar-shade-relocate/pom.xml create mode 100644 src/it/projects/MultiReleaseJar-shade-relocate/src/main/java/nl/example/Main.java create mode 100644 src/it/projects/MultiReleaseJar-shade-relocate/verify.groovy create mode 100644 src/it/projects/MultiReleaseJar-shade/invoker.properties create mode 100644 src/it/projects/MultiReleaseJar-shade/pom.xml create mode 100644 src/it/projects/MultiReleaseJar-shade/src/main/java/nl/example/Main.java create mode 100644 src/it/projects/MultiReleaseJar-shade/verify.groovy create mode 100644 src/it/setup/multiReleaseJar/invoker.properties create mode 100644 src/it/setup/multiReleaseJar/pom.xml create mode 100644 src/it/setup/multiReleaseJar/src/main/java/nl/basjes/maven/multijdk/AbstractJavaVersion.java create mode 100644 src/it/setup/multiReleaseJar/src/main/java/nl/basjes/maven/multijdk/App.java create mode 100644 src/it/setup/multiReleaseJar/src/main/java/nl/basjes/maven/multijdk/JavaVersion.java create mode 100644 src/it/setup/multiReleaseJar/src/main/java/nl/basjes/maven/multijdk/Main.java create mode 100644 src/it/setup/multiReleaseJar/src/main/java/nl/basjes/maven/multijdk/Unused.java create mode 100644 src/it/setup/multiReleaseJar/src/main/java11/nl/basjes/maven/multijdk/App.java create mode 100644 src/it/setup/multiReleaseJar/src/main/java11/nl/basjes/maven/multijdk/JavaVersion.java create mode 100644 src/it/setup/multiReleaseJar/src/main/java11/nl/basjes/maven/multijdk/OnlyUsedInJava17.java create mode 100644 src/it/setup/multiReleaseJar/src/main/java11/nl/basjes/maven/multijdk/SpecificToJava11.java create mode 100644 src/it/setup/multiReleaseJar/src/main/java11/nl/basjes/maven/multijdk/Unused.java create mode 100644 src/it/setup/multiReleaseJar/src/main/java17/nl/basjes/maven/multijdk/App.java create mode 100644 src/it/setup/multiReleaseJar/src/main/java17/nl/basjes/maven/multijdk/SpecificToJava17.java create mode 100644 src/it/setup/multiReleaseJar/src/main/java17/nl/basjes/maven/multijdk/Unused.java diff --git a/.github/workflows/maven-verify.yml b/.github/workflows/maven-verify.yml index 1a018d93..09c39de1 100644 --- a/.github/workflows/maven-verify.yml +++ b/.github/workflows/maven-verify.yml @@ -25,5 +25,9 @@ jobs: name: Verify uses: apache/maven-gh-actions-shared/.github/workflows/maven-verify.yml@v3 with: - ff-jdk: "21" + ff-jdk: | + 8 + 11 + 17 + 21 ff-jdk-distribution: "corretto" diff --git a/.gitignore b/.gitignore index 7495d7e2..8df47abf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -target/ +**/target/ .project .classpath .settings/ @@ -7,6 +7,7 @@ bin/ # Intellij *.ipr *.iml +**/*.iml .idea out/ .DS_Store diff --git a/pom.xml b/pom.xml index d822044e..052d922e 100644 --- a/pom.xml +++ b/pom.xml @@ -51,6 +51,9 @@ Torsten Curdt + + Niels Basjes + @@ -190,7 +193,7 @@ org.vafer jdependency - 2.9.0 + 2.9.1-SNAPSHOT org.apache.commons @@ -333,7 +336,13 @@ package true - src/it/projects + + setup/*/pom.xml + + + projects/*/pom.xml + + src/it src/it/mrm/settings.xml org.apache.maven.plugins:maven-shade-plugin:${project.version}:test-jar diff --git a/src/it/projects/MultiReleaseJar-shade-minimize-relocate/invoker.properties b/src/it/projects/MultiReleaseJar-shade-minimize-relocate/invoker.properties new file mode 100644 index 00000000..5b3a952b --- /dev/null +++ b/src/it/projects/MultiReleaseJar-shade-minimize-relocate/invoker.properties @@ -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. + +invoker.java.version = 17+ +invoker.goals.1=clean package +invoker.goals.2=-PJava8Test validate +invoker.goals.3=-PJava11Test validate +invoker.goals.4=-PJava17Test validate diff --git a/src/it/projects/MultiReleaseJar-shade-minimize-relocate/pom.xml b/src/it/projects/MultiReleaseJar-shade-minimize-relocate/pom.xml new file mode 100644 index 00000000..2bfd4442 --- /dev/null +++ b/src/it/projects/MultiReleaseJar-shade-minimize-relocate/pom.xml @@ -0,0 +1,287 @@ + + + + + + 4.0.0 + + org.apache.maven.its.shade.multirelease + shade + 1.0 + + MSHADE-406 Shade + + Shading multi release jar + + + + + nl.basjes.maven + multi-jdk + 1.0.0 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + org.apache.maven.plugins + maven-shade-plugin + @project.version@ + + + create-shaded-artifact + package + + shade + + + + + nl.example.Main + + + true + + + nl.basjes.maven.multijdk + nl.example.shaded.multijdk + + + + + + + + + + + + Java8Test + + + + org.apache.maven.plugins + maven-toolchains-plugin + + + + toolchain + + + + + + + 8 + + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.1.1 + + + + run-unshaded + validate + + exec + + + java + + -cp + target/original-shade-1.0.jar:../../setup/multiReleaseJar/target/multi-jdk-1.0.0.jar + nl.example.Main + + Java8-unshaded.log + + + + + run-shaded + validate + + exec + + + java + + -jar + target/shade-1.0.jar + + Java8-shaded.log + + + + + + + + + + + Java11Test + + + + org.apache.maven.plugins + maven-toolchains-plugin + + + + toolchain + + + + + + + 11 + + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.1.1 + + + + run-unshaded + validate + + exec + + + java + + -cp + target/original-shade-1.0.jar:../../setup/multiReleaseJar/target/multi-jdk-1.0.0.jar + nl.example.Main + + Java11-unshaded.log + + + + + run-shaded + validate + + exec + + + java + + -jar + target/shade-1.0.jar + + Java11-shaded.log + + + + + + + + + + + Java17Test + + + + org.apache.maven.plugins + maven-toolchains-plugin + + + + toolchain + + + + + + + 17 + + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.1.1 + + + + run-unshaded + validate + + exec + + + java + + -cp + target/original-shade-1.0.jar:../../setup/multiReleaseJar/target/multi-jdk-1.0.0.jar + nl.example.Main + + Java17-unshaded.log + + + + + run-shaded + validate + + exec + + + java + + -jar + target/shade-1.0.jar + + Java17-shaded.log + + + + + + + + + + + + diff --git a/src/it/projects/MultiReleaseJar-shade-minimize-relocate/src/main/java/nl/example/Main.java b/src/it/projects/MultiReleaseJar-shade-minimize-relocate/src/main/java/nl/example/Main.java new file mode 100644 index 00000000..9b0cdbd6 --- /dev/null +++ b/src/it/projects/MultiReleaseJar-shade-minimize-relocate/src/main/java/nl/example/Main.java @@ -0,0 +1,31 @@ +package nl.example; +/* + * 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. + */ + +import nl.basjes.maven.multijdk.JavaVersion; +import nl.basjes.maven.multijdk.App; + +public class Main { + public static void main(String[] args) { + JavaVersion javaVersion = new JavaVersion(); + System.out.println("Java detect: " + javaVersion.getCodeVersion()); + System.out.println("Java major : " + javaVersion.getJavaMajorVersion()); + System.out.println("App code : " + new App().doSomething()); + } +} \ No newline at end of file diff --git a/src/it/projects/MultiReleaseJar-shade-minimize-relocate/verify.groovy b/src/it/projects/MultiReleaseJar-shade-minimize-relocate/verify.groovy new file mode 100644 index 00000000..68092e59 --- /dev/null +++ b/src/it/projects/MultiReleaseJar-shade-minimize-relocate/verify.groovy @@ -0,0 +1,79 @@ +/* + * 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 jarFile = new java.util.jar.JarFile( new File( basedir, "target/shade-1.0.jar" ) ) +try +{ + // Although the original jar is NOT a Multi-Release, by shading in a Multi-Release jar this also must be a Multi-Release jar. + def manifestJarEntry = jarFile.getJarEntry("META-INF/MANIFEST.MF") + def manifestContent = jarFile.getInputStream(manifestJarEntry).getText() + assert manifestContent.contains( 'Multi-Release: true' ) + + File java8ShadedLog = new File( basedir, 'Java8-shaded.log' ) + File java8UnshadedLog = new File( basedir, 'Java8-unshaded.log' ) + File java11ShadedLog = new File( basedir, 'Java11-shaded.log' ) + File java11UnshadedLog = new File( basedir, 'Java11-unshaded.log' ) + File java17ShadedLog = new File( basedir, 'Java17-shaded.log' ) + File java17UnshadedLog = new File( basedir, 'Java17-unshaded.log' ) + + assert java8ShadedLog.getText().equals(java8UnshadedLog.getText()) + assert java11ShadedLog.getText().equals(java11UnshadedLog.getText()) + assert java17ShadedLog.getText().equals(java17UnshadedLog.getText()) + + // App class is unmodified + assert null != jarFile.getJarEntry( "nl/example/Main.class" ) + + // ALL original dependency classes must be gone + assert null == jarFile.getJarEntry( "nl/basjes/maven/multijdk/Unused.class" ) + assert null == jarFile.getJarEntry( "nl/basjes/maven/multijdk/JavaVersion.class" ) + assert null == jarFile.getJarEntry( "nl/basjes/maven/multijdk/AbstractJavaVersion.class" ) + assert null == jarFile.getJarEntry( "nl/basjes/maven/multijdk/App.class" ) + assert null == jarFile.getJarEntry( "nl/basjes/maven/multijdk/Main.class" ) + + assert null == jarFile.getJarEntry( "META-INF/versions/11/nl/basjes/maven/multijdk/Unused.class" ) + assert null == jarFile.getJarEntry( "META-INF/versions/11/nl/basjes/maven/multijdk/JavaVersion.class" ) + assert null == jarFile.getJarEntry( "META-INF/versions/11/nl/basjes/maven/multijdk/SpecificToJava11.class" ) + assert null == jarFile.getJarEntry( "META-INF/versions/11/nl/basjes/maven/multijdk/OnlyUsedInJava17.class" ) + assert null == jarFile.getJarEntry( "META-INF/versions/11/nl/basjes/maven/multijdk/App.class" ) + + assert null == jarFile.getJarEntry( "META-INF/versions/17/nl/basjes/maven/multijdk/Unused.class" ) + assert null == jarFile.getJarEntry( "META-INF/versions/17/nl/basjes/maven/multijdk/SpecificToJava17.class" ) + assert null == jarFile.getJarEntry( "META-INF/versions/17/nl/basjes/maven/multijdk/App.class" ) + + // The relocated must be minimized + assert null == jarFile.getJarEntry( "nl/example/shaded/multijdk/Unused.class" ) + assert null != jarFile.getJarEntry( "nl/example/shaded/multijdk/JavaVersion.class" ) + assert null != jarFile.getJarEntry( "nl/example/shaded/multijdk/AbstractJavaVersion.class" ) + assert null != jarFile.getJarEntry( "nl/example/shaded/multijdk/App.class" ) + assert null == jarFile.getJarEntry( "nl/example/shaded/multijdk/Main.class" ) + + assert null == jarFile.getJarEntry( "META-INF/versions/11/nl/example/shaded/multijdk/Unused.class" ) + assert null != jarFile.getJarEntry( "META-INF/versions/11/nl/example/shaded/multijdk/JavaVersion.class" ) + assert null != jarFile.getJarEntry( "META-INF/versions/11/nl/example/shaded/multijdk/SpecificToJava11.class" ) + assert null != jarFile.getJarEntry( "META-INF/versions/11/nl/example/shaded/multijdk/OnlyUsedInJava17.class" ) + assert null != jarFile.getJarEntry( "META-INF/versions/11/nl/example/shaded/multijdk/App.class" ) + + assert null == jarFile.getJarEntry( "META-INF/versions/17/nl/example/shaded/multijdk/Unused.class" ) + assert null != jarFile.getJarEntry( "META-INF/versions/17/nl/example/shaded/multijdk/SpecificToJava17.class" ) + assert null != jarFile.getJarEntry( "META-INF/versions/17/nl/example/shaded/multijdk/App.class" ) +} +finally +{ + jarFile.close() +} diff --git a/src/it/projects/MultiReleaseJar-shade-minimize/invoker.properties b/src/it/projects/MultiReleaseJar-shade-minimize/invoker.properties new file mode 100644 index 00000000..5b3a952b --- /dev/null +++ b/src/it/projects/MultiReleaseJar-shade-minimize/invoker.properties @@ -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. + +invoker.java.version = 17+ +invoker.goals.1=clean package +invoker.goals.2=-PJava8Test validate +invoker.goals.3=-PJava11Test validate +invoker.goals.4=-PJava17Test validate diff --git a/src/it/projects/MultiReleaseJar-shade-minimize/pom.xml b/src/it/projects/MultiReleaseJar-shade-minimize/pom.xml new file mode 100644 index 00000000..2eab5f0b --- /dev/null +++ b/src/it/projects/MultiReleaseJar-shade-minimize/pom.xml @@ -0,0 +1,287 @@ + + + + + + 4.0.0 + + org.apache.maven.its.shade.multirelease + shade + 1.0 + + MSHADE-406 Shade + + Shading multi release jar + + + + + nl.basjes.maven + multi-jdk + 1.0.0 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + org.apache.maven.plugins + maven-shade-plugin + @project.version@ + + + create-shaded-artifact + package + + shade + + + + + nl.example.Main + + + true + + + + + + + + + + + + + + + + Java8Test + + + + org.apache.maven.plugins + maven-toolchains-plugin + + + + toolchain + + + + + + + 8 + + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.1.1 + + + + run-unshaded + validate + + exec + + + java + + -cp + target/original-shade-1.0.jar:../../setup/multiReleaseJar/target/multi-jdk-1.0.0.jar + nl.example.Main + + Java8-unshaded.log + + + + + run-shaded + validate + + exec + + + java + + -jar + target/shade-1.0.jar + + Java8-shaded.log + + + + + + + + + + + Java11Test + + + + org.apache.maven.plugins + maven-toolchains-plugin + + + + toolchain + + + + + + + 11 + + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.1.1 + + + + run-unshaded + validate + + exec + + + java + + -cp + target/original-shade-1.0.jar:../../setup/multiReleaseJar/target/multi-jdk-1.0.0.jar + nl.example.Main + + Java11-unshaded.log + + + + + run-shaded + validate + + exec + + + java + + -jar + target/shade-1.0.jar + + Java11-shaded.log + + + + + + + + + + + Java17Test + + + + org.apache.maven.plugins + maven-toolchains-plugin + + + + toolchain + + + + + + + 17 + + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.1.1 + + + + run-unshaded + validate + + exec + + + java + + -cp + target/original-shade-1.0.jar:../../setup/multiReleaseJar/target/multi-jdk-1.0.0.jar + nl.example.Main + + Java17-unshaded.log + + + + + run-shaded + validate + + exec + + + java + + -jar + target/shade-1.0.jar + + Java17-shaded.log + + + + + + + + + + + + diff --git a/src/it/projects/MultiReleaseJar-shade-minimize/src/main/java/nl/example/Main.java b/src/it/projects/MultiReleaseJar-shade-minimize/src/main/java/nl/example/Main.java new file mode 100644 index 00000000..9b0cdbd6 --- /dev/null +++ b/src/it/projects/MultiReleaseJar-shade-minimize/src/main/java/nl/example/Main.java @@ -0,0 +1,31 @@ +package nl.example; +/* + * 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. + */ + +import nl.basjes.maven.multijdk.JavaVersion; +import nl.basjes.maven.multijdk.App; + +public class Main { + public static void main(String[] args) { + JavaVersion javaVersion = new JavaVersion(); + System.out.println("Java detect: " + javaVersion.getCodeVersion()); + System.out.println("Java major : " + javaVersion.getJavaMajorVersion()); + System.out.println("App code : " + new App().doSomething()); + } +} \ No newline at end of file diff --git a/src/it/projects/MultiReleaseJar-shade-minimize/verify.groovy b/src/it/projects/MultiReleaseJar-shade-minimize/verify.groovy new file mode 100644 index 00000000..911719d3 --- /dev/null +++ b/src/it/projects/MultiReleaseJar-shade-minimize/verify.groovy @@ -0,0 +1,60 @@ +/* + * 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 jarFile = new java.util.jar.JarFile( new File( basedir, "target/shade-1.0.jar" ) ) +try +{ + // Although the original jar is NOT a Multi-Release, by shading in a Multi-Release jar this also must be a Multi-Release jar. + def manifestJarEntry = jarFile.getJarEntry("META-INF/MANIFEST.MF") + def manifestContent = jarFile.getInputStream(manifestJarEntry).getText() + assert manifestContent.contains( 'Multi-Release: true' ) + + File java8ShadedLog = new File( basedir, 'Java8-shaded.log' ) + File java8UnshadedLog = new File( basedir, 'Java8-unshaded.log' ) + File java11ShadedLog = new File( basedir, 'Java11-shaded.log' ) + File java11UnshadedLog = new File( basedir, 'Java11-unshaded.log' ) + File java17ShadedLog = new File( basedir, 'Java17-shaded.log' ) + File java17UnshadedLog = new File( basedir, 'Java17-unshaded.log' ) + + assert java8ShadedLog.getText().equals(java8UnshadedLog.getText()) + assert java11ShadedLog.getText().equals(java11UnshadedLog.getText()) + assert java17ShadedLog.getText().equals(java17UnshadedLog.getText()) + + assert null != jarFile.getJarEntry( "nl/example/Main.class" ) + + assert null == jarFile.getJarEntry( "nl/basjes/maven/multijdk/Unused.class" ) + assert null != jarFile.getJarEntry( "nl/basjes/maven/multijdk/JavaVersion.class" ) + assert null != jarFile.getJarEntry( "nl/basjes/maven/multijdk/AbstractJavaVersion.class" ) + assert null != jarFile.getJarEntry( "nl/basjes/maven/multijdk/App.class" ) + assert null == jarFile.getJarEntry( "nl/basjes/maven/multijdk/Main.class" ) + + assert null == jarFile.getJarEntry( "META-INF/versions/11/nl/basjes/maven/multijdk/Unused.class" ) + assert null != jarFile.getJarEntry( "META-INF/versions/11/nl/basjes/maven/multijdk/JavaVersion.class" ) + assert null != jarFile.getJarEntry( "META-INF/versions/11/nl/basjes/maven/multijdk/SpecificToJava11.class" ) + assert null != jarFile.getJarEntry( "META-INF/versions/11/nl/basjes/maven/multijdk/OnlyUsedInJava17.class" ) + assert null != jarFile.getJarEntry( "META-INF/versions/11/nl/basjes/maven/multijdk/App.class" ) + + assert null == jarFile.getJarEntry( "META-INF/versions/17/nl/basjes/maven/multijdk/Unused.class" ) + assert null != jarFile.getJarEntry( "META-INF/versions/17/nl/basjes/maven/multijdk/SpecificToJava17.class" ) + assert null != jarFile.getJarEntry( "META-INF/versions/17/nl/basjes/maven/multijdk/App.class" ) +} +finally +{ + jarFile.close() +} diff --git a/src/it/projects/MultiReleaseJar-shade-relocate/invoker.properties b/src/it/projects/MultiReleaseJar-shade-relocate/invoker.properties new file mode 100644 index 00000000..5b3a952b --- /dev/null +++ b/src/it/projects/MultiReleaseJar-shade-relocate/invoker.properties @@ -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. + +invoker.java.version = 17+ +invoker.goals.1=clean package +invoker.goals.2=-PJava8Test validate +invoker.goals.3=-PJava11Test validate +invoker.goals.4=-PJava17Test validate diff --git a/src/it/projects/MultiReleaseJar-shade-relocate/pom.xml b/src/it/projects/MultiReleaseJar-shade-relocate/pom.xml new file mode 100644 index 00000000..75e69235 --- /dev/null +++ b/src/it/projects/MultiReleaseJar-shade-relocate/pom.xml @@ -0,0 +1,287 @@ + + + + + + 4.0.0 + + org.apache.maven.its.shade.multirelease + shade + 1.0 + + MSHADE-406 Shade + + Shading multi release jar + + + + + nl.basjes.maven + multi-jdk + 1.0.0 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + org.apache.maven.plugins + maven-shade-plugin + @project.version@ + + + create-shaded-artifact + package + + shade + + + + + nl.example.Main + + + + + + nl.basjes.maven.multijdk + nl.example.shaded.multijdk + + + + + + + + + + + + Java8Test + + + + org.apache.maven.plugins + maven-toolchains-plugin + + + + toolchain + + + + + + + 8 + + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.1.1 + + + + run-unshaded + validate + + exec + + + java + + -cp + target/original-shade-1.0.jar:../../setup/multiReleaseJar/target/multi-jdk-1.0.0.jar + nl.example.Main + + Java8-unshaded.log + + + + + run-shaded + validate + + exec + + + java + + -jar + target/shade-1.0.jar + + Java8-shaded.log + + + + + + + + + + + Java11Test + + + + org.apache.maven.plugins + maven-toolchains-plugin + + + + toolchain + + + + + + + 11 + + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.1.1 + + + + run-unshaded + validate + + exec + + + java + + -cp + target/original-shade-1.0.jar:../../setup/multiReleaseJar/target/multi-jdk-1.0.0.jar + nl.example.Main + + Java11-unshaded.log + + + + + run-shaded + validate + + exec + + + java + + -jar + target/shade-1.0.jar + + Java11-shaded.log + + + + + + + + + + + Java17Test + + + + org.apache.maven.plugins + maven-toolchains-plugin + + + + toolchain + + + + + + + 17 + + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.1.1 + + + + run-unshaded + validate + + exec + + + java + + -cp + target/original-shade-1.0.jar:../../setup/multiReleaseJar/target/multi-jdk-1.0.0.jar + nl.example.Main + + Java17-unshaded.log + + + + + run-shaded + validate + + exec + + + java + + -jar + target/shade-1.0.jar + + Java17-shaded.log + + + + + + + + + + + + diff --git a/src/it/projects/MultiReleaseJar-shade-relocate/src/main/java/nl/example/Main.java b/src/it/projects/MultiReleaseJar-shade-relocate/src/main/java/nl/example/Main.java new file mode 100644 index 00000000..9b0cdbd6 --- /dev/null +++ b/src/it/projects/MultiReleaseJar-shade-relocate/src/main/java/nl/example/Main.java @@ -0,0 +1,31 @@ +package nl.example; +/* + * 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. + */ + +import nl.basjes.maven.multijdk.JavaVersion; +import nl.basjes.maven.multijdk.App; + +public class Main { + public static void main(String[] args) { + JavaVersion javaVersion = new JavaVersion(); + System.out.println("Java detect: " + javaVersion.getCodeVersion()); + System.out.println("Java major : " + javaVersion.getJavaMajorVersion()); + System.out.println("App code : " + new App().doSomething()); + } +} \ No newline at end of file diff --git a/src/it/projects/MultiReleaseJar-shade-relocate/verify.groovy b/src/it/projects/MultiReleaseJar-shade-relocate/verify.groovy new file mode 100644 index 00000000..5aabd8d9 --- /dev/null +++ b/src/it/projects/MultiReleaseJar-shade-relocate/verify.groovy @@ -0,0 +1,79 @@ +/* + * 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 jarFile = new java.util.jar.JarFile( new File( basedir, "target/shade-1.0.jar" ) ) +try +{ + // Although the original jar is NOT a Multi-Release, by shading in a Multi-Release jar this also must be a Multi-Release jar. + def manifestJarEntry = jarFile.getJarEntry("META-INF/MANIFEST.MF") + def manifestContent = jarFile.getInputStream(manifestJarEntry).getText() + assert manifestContent.contains( 'Multi-Release: true' ) + + File java8ShadedLog = new File( basedir, 'Java8-shaded.log' ) + File java8UnshadedLog = new File( basedir, 'Java8-unshaded.log' ) + File java11ShadedLog = new File( basedir, 'Java11-shaded.log' ) + File java11UnshadedLog = new File( basedir, 'Java11-unshaded.log' ) + File java17ShadedLog = new File( basedir, 'Java17-shaded.log' ) + File java17UnshadedLog = new File( basedir, 'Java17-unshaded.log' ) + + assert java8ShadedLog.getText().equals(java8UnshadedLog.getText()) + assert java11ShadedLog.getText().equals(java11UnshadedLog.getText()) + assert java17ShadedLog.getText().equals(java17UnshadedLog.getText()) + + // App class is unmodified + assert null != jarFile.getJarEntry( "nl/example/Main.class" ) + + // ALL original dependency classes must be gone + assert null == jarFile.getJarEntry( "nl/basjes/maven/multijdk/Unused.class" ) + assert null == jarFile.getJarEntry( "nl/basjes/maven/multijdk/JavaVersion.class" ) + assert null == jarFile.getJarEntry( "nl/basjes/maven/multijdk/AbstractJavaVersion.class" ) + assert null == jarFile.getJarEntry( "nl/basjes/maven/multijdk/App.class" ) + assert null == jarFile.getJarEntry( "nl/basjes/maven/multijdk/Main.class" ) + + assert null == jarFile.getJarEntry( "META-INF/versions/11/nl/basjes/maven/multijdk/Unused.class" ) + assert null == jarFile.getJarEntry( "META-INF/versions/11/nl/basjes/maven/multijdk/JavaVersion.class" ) + assert null == jarFile.getJarEntry( "META-INF/versions/11/nl/basjes/maven/multijdk/SpecificToJava11.class" ) + assert null == jarFile.getJarEntry( "META-INF/versions/11/nl/basjes/maven/multijdk/OnlyUsedInJava17.class" ) + assert null == jarFile.getJarEntry( "META-INF/versions/11/nl/basjes/maven/multijdk/App.class" ) + + assert null == jarFile.getJarEntry( "META-INF/versions/17/nl/basjes/maven/multijdk/Unused.class" ) + assert null == jarFile.getJarEntry( "META-INF/versions/17/nl/basjes/maven/multijdk/SpecificToJava17.class" ) + assert null == jarFile.getJarEntry( "META-INF/versions/17/nl/basjes/maven/multijdk/App.class" ) + + // The relocated must NOT be minimized + assert null != jarFile.getJarEntry( "nl/example/shaded/multijdk/Unused.class" ) + assert null != jarFile.getJarEntry( "nl/example/shaded/multijdk/JavaVersion.class" ) + assert null != jarFile.getJarEntry( "nl/example/shaded/multijdk/AbstractJavaVersion.class" ) + assert null != jarFile.getJarEntry( "nl/example/shaded/multijdk/App.class" ) + assert null != jarFile.getJarEntry( "nl/example/shaded/multijdk/Main.class" ) + + assert null != jarFile.getJarEntry( "META-INF/versions/11/nl/example/shaded/multijdk/Unused.class" ) + assert null != jarFile.getJarEntry( "META-INF/versions/11/nl/example/shaded/multijdk/JavaVersion.class" ) + assert null != jarFile.getJarEntry( "META-INF/versions/11/nl/example/shaded/multijdk/SpecificToJava11.class" ) + assert null != jarFile.getJarEntry( "META-INF/versions/11/nl/example/shaded/multijdk/OnlyUsedInJava17.class" ) + assert null != jarFile.getJarEntry( "META-INF/versions/11/nl/example/shaded/multijdk/App.class" ) + + assert null != jarFile.getJarEntry( "META-INF/versions/17/nl/example/shaded/multijdk/Unused.class" ) + assert null != jarFile.getJarEntry( "META-INF/versions/17/nl/example/shaded/multijdk/SpecificToJava17.class" ) + assert null != jarFile.getJarEntry( "META-INF/versions/17/nl/example/shaded/multijdk/App.class" ) +} +finally +{ + jarFile.close() +} diff --git a/src/it/projects/MultiReleaseJar-shade/invoker.properties b/src/it/projects/MultiReleaseJar-shade/invoker.properties new file mode 100644 index 00000000..5b3a952b --- /dev/null +++ b/src/it/projects/MultiReleaseJar-shade/invoker.properties @@ -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. + +invoker.java.version = 17+ +invoker.goals.1=clean package +invoker.goals.2=-PJava8Test validate +invoker.goals.3=-PJava11Test validate +invoker.goals.4=-PJava17Test validate diff --git a/src/it/projects/MultiReleaseJar-shade/pom.xml b/src/it/projects/MultiReleaseJar-shade/pom.xml new file mode 100644 index 00000000..d6b54061 --- /dev/null +++ b/src/it/projects/MultiReleaseJar-shade/pom.xml @@ -0,0 +1,287 @@ + + + + + + 4.0.0 + + org.apache.maven.its.shade.multirelease + shade + 1.0 + + MSHADE-406 Shade + + Shading multi release jar + + + + + nl.basjes.maven + multi-jdk + 1.0.0 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + org.apache.maven.plugins + maven-shade-plugin + @project.version@ + + + create-shaded-artifact + package + + shade + + + + + nl.example.Main + + + + + + + + + + + + + + + + + + + Java8Test + + + + org.apache.maven.plugins + maven-toolchains-plugin + + + + toolchain + + + + + + + 8 + + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.1.1 + + + + run-unshaded + validate + + exec + + + java + + -cp + target/original-shade-1.0.jar:../../setup/multiReleaseJar/target/multi-jdk-1.0.0.jar + nl.example.Main + + Java8-unshaded.log + + + + + run-shaded + validate + + exec + + + java + + -jar + target/shade-1.0.jar + + Java8-shaded.log + + + + + + + + + + + Java11Test + + + + org.apache.maven.plugins + maven-toolchains-plugin + + + + toolchain + + + + + + + 11 + + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.1.1 + + + + run-unshaded + validate + + exec + + + java + + -cp + target/original-shade-1.0.jar:../../setup/multiReleaseJar/target/multi-jdk-1.0.0.jar + nl.example.Main + + Java11-unshaded.log + + + + + run-shaded + validate + + exec + + + java + + -jar + target/shade-1.0.jar + + Java11-shaded.log + + + + + + + + + + + Java17Test + + + + org.apache.maven.plugins + maven-toolchains-plugin + + + + toolchain + + + + + + + 17 + + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.1.1 + + + + run-unshaded + validate + + exec + + + java + + -cp + target/original-shade-1.0.jar:../../setup/multiReleaseJar/target/multi-jdk-1.0.0.jar + nl.example.Main + + Java17-unshaded.log + + + + + run-shaded + validate + + exec + + + java + + -jar + target/shade-1.0.jar + + Java17-shaded.log + + + + + + + + + + + + diff --git a/src/it/projects/MultiReleaseJar-shade/src/main/java/nl/example/Main.java b/src/it/projects/MultiReleaseJar-shade/src/main/java/nl/example/Main.java new file mode 100644 index 00000000..9b0cdbd6 --- /dev/null +++ b/src/it/projects/MultiReleaseJar-shade/src/main/java/nl/example/Main.java @@ -0,0 +1,31 @@ +package nl.example; +/* + * 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. + */ + +import nl.basjes.maven.multijdk.JavaVersion; +import nl.basjes.maven.multijdk.App; + +public class Main { + public static void main(String[] args) { + JavaVersion javaVersion = new JavaVersion(); + System.out.println("Java detect: " + javaVersion.getCodeVersion()); + System.out.println("Java major : " + javaVersion.getJavaMajorVersion()); + System.out.println("App code : " + new App().doSomething()); + } +} \ No newline at end of file diff --git a/src/it/projects/MultiReleaseJar-shade/verify.groovy b/src/it/projects/MultiReleaseJar-shade/verify.groovy new file mode 100644 index 00000000..e05ffbb9 --- /dev/null +++ b/src/it/projects/MultiReleaseJar-shade/verify.groovy @@ -0,0 +1,61 @@ +/* + * 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 jarFile = new java.util.jar.JarFile( new File( basedir, "target/shade-1.0.jar" ) ) +try +{ + // Although the original jar is NOT a Multi-Release, by shading in a Multi-Release jar this also must be a Multi-Release jar. + def manifestJarEntry = jarFile.getJarEntry("META-INF/MANIFEST.MF") + def manifestContent = jarFile.getInputStream(manifestJarEntry).getText() + assert manifestContent.contains( 'Multi-Release: true' ) + + File java8ShadedLog = new File( basedir, 'Java8-shaded.log' ) + File java8UnshadedLog = new File( basedir, 'Java8-unshaded.log' ) + File java11ShadedLog = new File( basedir, 'Java11-shaded.log' ) + File java11UnshadedLog = new File( basedir, 'Java11-unshaded.log' ) + File java17ShadedLog = new File( basedir, 'Java17-shaded.log' ) + File java17UnshadedLog = new File( basedir, 'Java17-unshaded.log' ) + + assert java8ShadedLog.getText().equals(java8UnshadedLog.getText()) + assert java11ShadedLog.getText().equals(java11UnshadedLog.getText()) + assert java17ShadedLog.getText().equals(java17UnshadedLog.getText()) + + assert null != jarFile.getJarEntry( "nl/example/Main.class" ) + + assert null != jarFile.getJarEntry( "nl/basjes/maven/multijdk/Unused.class" ) + assert null != jarFile.getJarEntry( "nl/basjes/maven/multijdk/JavaVersion.class" ) + assert null != jarFile.getJarEntry( "nl/basjes/maven/multijdk/AbstractJavaVersion.class" ) + assert null != jarFile.getJarEntry( "nl/basjes/maven/multijdk/App.class" ) + assert null != jarFile.getJarEntry( "nl/basjes/maven/multijdk/Main.class" ) + + assert null != jarFile.getJarEntry( "META-INF/versions/11/nl/basjes/maven/multijdk/Unused.class" ) + assert null != jarFile.getJarEntry( "META-INF/versions/11/nl/basjes/maven/multijdk/JavaVersion.class" ) + assert null != jarFile.getJarEntry( "META-INF/versions/11/nl/basjes/maven/multijdk/SpecificToJava11.class" ) + assert null != jarFile.getJarEntry( "META-INF/versions/11/nl/basjes/maven/multijdk/OnlyUsedInJava17.class" ) + assert null != jarFile.getJarEntry( "META-INF/versions/11/nl/basjes/maven/multijdk/App.class" ) + + assert null != jarFile.getJarEntry( "META-INF/versions/17/nl/basjes/maven/multijdk/Unused.class" ) + assert null != jarFile.getJarEntry( "META-INF/versions/17/nl/basjes/maven/multijdk/SpecificToJava17.class" ) + assert null != jarFile.getJarEntry( "META-INF/versions/17/nl/basjes/maven/multijdk/App.class" ) +} +finally +{ + jarFile.close() +} + diff --git a/src/it/setup/multiReleaseJar/invoker.properties b/src/it/setup/multiReleaseJar/invoker.properties new file mode 100644 index 00000000..e7637a01 --- /dev/null +++ b/src/it/setup/multiReleaseJar/invoker.properties @@ -0,0 +1,19 @@ +# 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.java.version = 17+ +invoker.goals = install diff --git a/src/it/setup/multiReleaseJar/pom.xml b/src/it/setup/multiReleaseJar/pom.xml new file mode 100644 index 00000000..2e88254d --- /dev/null +++ b/src/it/setup/multiReleaseJar/pom.xml @@ -0,0 +1,96 @@ + + + + + + 4.0.0 + + Multi Release Jar + + nl.basjes.maven + multi-jdk + 1.0.0 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + java-11 + + compile + + + 11 + 11 + 11 + ${project.basedir}/src/main/java11 + true + + + + + java-17 + + compile + + + 17 + 17 + 17 + ${project.basedir}/src/main/java17 + true + + + + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + nl.basjes.maven.multijdk.Main + + + true + + + + + + + + + + diff --git a/src/it/setup/multiReleaseJar/src/main/java/nl/basjes/maven/multijdk/AbstractJavaVersion.java b/src/it/setup/multiReleaseJar/src/main/java/nl/basjes/maven/multijdk/AbstractJavaVersion.java new file mode 100644 index 00000000..b8c9c511 --- /dev/null +++ b/src/it/setup/multiReleaseJar/src/main/java/nl/basjes/maven/multijdk/AbstractJavaVersion.java @@ -0,0 +1,35 @@ +package nl.basjes.maven.multijdk; +/* + * 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. + */ + +public abstract class AbstractJavaVersion { + + public abstract String getCodeVersion(); + public abstract String getJavaVersion(); + + public String getJavaMajorVersion() { + String version = getJavaVersion(); + String[] versionElements = version.split("\\."); + String majorVersion = versionElements[0]; + if ("1".equals(majorVersion)) { + majorVersion = versionElements[1]; + } + return majorVersion; + } +} diff --git a/src/it/setup/multiReleaseJar/src/main/java/nl/basjes/maven/multijdk/App.java b/src/it/setup/multiReleaseJar/src/main/java/nl/basjes/maven/multijdk/App.java new file mode 100644 index 00000000..a2f8cf3e --- /dev/null +++ b/src/it/setup/multiReleaseJar/src/main/java/nl/basjes/maven/multijdk/App.java @@ -0,0 +1,25 @@ +package nl.basjes.maven.multijdk; +/* + * 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. + */ + +public class App { + public String doSomething() { + return "base"; + } +} diff --git a/src/it/setup/multiReleaseJar/src/main/java/nl/basjes/maven/multijdk/JavaVersion.java b/src/it/setup/multiReleaseJar/src/main/java/nl/basjes/maven/multijdk/JavaVersion.java new file mode 100644 index 00000000..1e227f4f --- /dev/null +++ b/src/it/setup/multiReleaseJar/src/main/java/nl/basjes/maven/multijdk/JavaVersion.java @@ -0,0 +1,29 @@ +package nl.basjes.maven.multijdk; +/* + * 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. + */ + +public class JavaVersion extends AbstractJavaVersion { + public String getCodeVersion() { + return "8 (base)"; + } + + public String getJavaVersion() { + return System.getProperty("java.version"); + } +} diff --git a/src/it/setup/multiReleaseJar/src/main/java/nl/basjes/maven/multijdk/Main.java b/src/it/setup/multiReleaseJar/src/main/java/nl/basjes/maven/multijdk/Main.java new file mode 100644 index 00000000..fe750f12 --- /dev/null +++ b/src/it/setup/multiReleaseJar/src/main/java/nl/basjes/maven/multijdk/Main.java @@ -0,0 +1,29 @@ +package nl.basjes.maven.multijdk; +/* + * 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. + */ + +public class Main { + public static void main(String[] args) { + JavaVersion javaVersion = new JavaVersion(); + System.out.println("Java detect: " + javaVersion.getCodeVersion()); + System.out.println("Java major : " + javaVersion.getJavaMajorVersion()); + System.out.println("App code : " + new App().doSomething()); + System.out.println("Unused : " + new Unused().doSomething()); + } +} \ No newline at end of file diff --git a/src/it/setup/multiReleaseJar/src/main/java/nl/basjes/maven/multijdk/Unused.java b/src/it/setup/multiReleaseJar/src/main/java/nl/basjes/maven/multijdk/Unused.java new file mode 100644 index 00000000..13d9d84e --- /dev/null +++ b/src/it/setup/multiReleaseJar/src/main/java/nl/basjes/maven/multijdk/Unused.java @@ -0,0 +1,25 @@ +package nl.basjes.maven.multijdk; +/* + * 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. + */ + +public class Unused { + public String doSomething() { + return "base"; + } +} diff --git a/src/it/setup/multiReleaseJar/src/main/java11/nl/basjes/maven/multijdk/App.java b/src/it/setup/multiReleaseJar/src/main/java11/nl/basjes/maven/multijdk/App.java new file mode 100644 index 00000000..b9e47fe2 --- /dev/null +++ b/src/it/setup/multiReleaseJar/src/main/java11/nl/basjes/maven/multijdk/App.java @@ -0,0 +1,25 @@ +package nl.basjes.maven.multijdk; +/* + * 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. + */ + +public class App { + public String doSomething() { + return new SpecificToJava11().doSomething() + " 11"; + } +} diff --git a/src/it/setup/multiReleaseJar/src/main/java11/nl/basjes/maven/multijdk/JavaVersion.java b/src/it/setup/multiReleaseJar/src/main/java11/nl/basjes/maven/multijdk/JavaVersion.java new file mode 100644 index 00000000..44ca9554 --- /dev/null +++ b/src/it/setup/multiReleaseJar/src/main/java11/nl/basjes/maven/multijdk/JavaVersion.java @@ -0,0 +1,36 @@ +package nl.basjes.maven.multijdk; +/* + * 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. + */ + +import java.util.stream.Collectors; + +public class JavaVersion extends AbstractJavaVersion { + public String getCodeVersion() { + return "11"; + } + + public String getJavaVersion() { + return Runtime.version() + .version() + .stream() + .limit(3) + .map(Object::toString) + .collect(Collectors.joining(".")); + } +} diff --git a/src/it/setup/multiReleaseJar/src/main/java11/nl/basjes/maven/multijdk/OnlyUsedInJava17.java b/src/it/setup/multiReleaseJar/src/main/java11/nl/basjes/maven/multijdk/OnlyUsedInJava17.java new file mode 100644 index 00000000..9668eea7 --- /dev/null +++ b/src/it/setup/multiReleaseJar/src/main/java11/nl/basjes/maven/multijdk/OnlyUsedInJava17.java @@ -0,0 +1,25 @@ +package nl.basjes.maven.multijdk; +/* + * 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. + */ + +public class OnlyUsedInJava17 { + public String doSomething() { + return new JavaVersion().getJavaMajorVersion(); + } +} diff --git a/src/it/setup/multiReleaseJar/src/main/java11/nl/basjes/maven/multijdk/SpecificToJava11.java b/src/it/setup/multiReleaseJar/src/main/java11/nl/basjes/maven/multijdk/SpecificToJava11.java new file mode 100644 index 00000000..23c7c3f2 --- /dev/null +++ b/src/it/setup/multiReleaseJar/src/main/java11/nl/basjes/maven/multijdk/SpecificToJava11.java @@ -0,0 +1,25 @@ +package nl.basjes.maven.multijdk; +/* + * 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. + */ + +public class SpecificToJava11 { + public String doSomething() { + return "java"; + } +} diff --git a/src/it/setup/multiReleaseJar/src/main/java11/nl/basjes/maven/multijdk/Unused.java b/src/it/setup/multiReleaseJar/src/main/java11/nl/basjes/maven/multijdk/Unused.java new file mode 100644 index 00000000..c7e6145f --- /dev/null +++ b/src/it/setup/multiReleaseJar/src/main/java11/nl/basjes/maven/multijdk/Unused.java @@ -0,0 +1,25 @@ +package nl.basjes.maven.multijdk; +/* + * 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. + */ + +public class Unused { + public String doSomething() { + return "java 11"; + } +} diff --git a/src/it/setup/multiReleaseJar/src/main/java17/nl/basjes/maven/multijdk/App.java b/src/it/setup/multiReleaseJar/src/main/java17/nl/basjes/maven/multijdk/App.java new file mode 100644 index 00000000..8b5e6f74 --- /dev/null +++ b/src/it/setup/multiReleaseJar/src/main/java17/nl/basjes/maven/multijdk/App.java @@ -0,0 +1,25 @@ +package nl.basjes.maven.multijdk; +/* + * 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. + */ + +public class App { + public String doSomething() { + return new SpecificToJava17().doSomething() + " " + new OnlyUsedInJava17().doSomething(); + } +} diff --git a/src/it/setup/multiReleaseJar/src/main/java17/nl/basjes/maven/multijdk/SpecificToJava17.java b/src/it/setup/multiReleaseJar/src/main/java17/nl/basjes/maven/multijdk/SpecificToJava17.java new file mode 100644 index 00000000..6f89cde2 --- /dev/null +++ b/src/it/setup/multiReleaseJar/src/main/java17/nl/basjes/maven/multijdk/SpecificToJava17.java @@ -0,0 +1,25 @@ +package nl.basjes.maven.multijdk; +/* + * 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. + */ + +public class SpecificToJava17 { + public String doSomething() { + return "java"; + } +} diff --git a/src/it/setup/multiReleaseJar/src/main/java17/nl/basjes/maven/multijdk/Unused.java b/src/it/setup/multiReleaseJar/src/main/java17/nl/basjes/maven/multijdk/Unused.java new file mode 100644 index 00000000..56598875 --- /dev/null +++ b/src/it/setup/multiReleaseJar/src/main/java17/nl/basjes/maven/multijdk/Unused.java @@ -0,0 +1,24 @@ +package nl.basjes.maven.multijdk; +/* + * 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. + */ +public class Unused { + public String doSomething() { + return "java 17"; + } +} 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 3d14fd21..53fe8364 100644 --- a/src/main/java/org/apache/maven/plugins/shade/DefaultShader.java +++ b/src/main/java/org/apache/maven/plugins/shade/DefaultShader.java @@ -70,6 +70,7 @@ import org.objectweb.asm.commons.Remapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.vafer.jdependency.Clazz; /** * @author Jason van Zyl @@ -593,8 +594,13 @@ private void addRemappedClass( renamedClass = originalClass; } - // Need to take the .class off for remapping evaluation - String mappedName = packageMapper.map(name.substring(0, name.indexOf('.')), true, false); + String mappedName; + if (Clazz.isMultiReleaseClassFile(name)) { + mappedName = packageMapper.map(name, true, false); // .substring(0, name.indexOf('.')); + } else { + // Need to take the .class off for remapping evaluation + mappedName = packageMapper.map(name.substring(0, name.indexOf('.')), true, false); + } try { // Now we put it back on so the class file is written out with the right extension. @@ -728,11 +734,19 @@ public String map(String entityName, boolean mapPaths, final boolean mapPackages String prefix = ""; String suffix = ""; - Matcher m = CLASS_PATTERN.matcher(entityName); - if (m.matches()) { - prefix = m.group(1) + "L"; - suffix = ";"; - entityName = m.group(2); + boolean isMultiReleaseClassFile = Clazz.isMultiReleaseClassFile(entityName); + + if (isMultiReleaseClassFile) { + Clazz.ParsedFileName parsedFileName = Clazz.parseClassFileName(entityName); + prefix = "META-INF/versions/" + parsedFileName.forJava + "/"; + entityName = parsedFileName.className.replace(".", "/"); + } else { + Matcher m = CLASS_PATTERN.matcher(entityName); + if (m.matches()) { + prefix = m.group(1) + "L"; + suffix = ";"; + entityName = m.group(2); + } } for (Relocator r : relocators) { 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 bfc01223..2e1c1994 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 @@ -139,8 +139,7 @@ public MinijarFilter(MavenProject project, Log log, List simpleFil } } } - removeSpecificallyIncludedClasses( - project, simpleFilters == null ? Collections.emptyList() : simpleFilters); + removeSpecificallyIncludedClasses(project, simpleFilters == null ? Collections.emptyList() : simpleFilters); removeServices(project, cp); } } @@ -325,11 +324,14 @@ public boolean canFilter(File jar) { @Override public boolean isFiltered(String classFile) { - String className = classFile.replace('/', '.').replaceFirst("\\.class$", ""); - Clazz clazz = new Clazz(className); + Clazz.ParsedFileName parsedFileName = Clazz.parseClassFileName(classFile); + if (parsedFileName == null) { + return false; + } + Clazz clazz = new Clazz(parsedFileName.className); if (removable != null && removable.contains(clazz)) { - log.debug("Removing " + className); + log.debug("Removing " + parsedFileName.className); classesRemoved += 1; return true; } diff --git a/src/main/java/org/apache/maven/plugins/shade/relocation/SimpleRelocator.java b/src/main/java/org/apache/maven/plugins/shade/relocation/SimpleRelocator.java index bb31af0a..687cb059 100644 --- a/src/main/java/org/apache/maven/plugins/shade/relocation/SimpleRelocator.java +++ b/src/main/java/org/apache/maven/plugins/shade/relocation/SimpleRelocator.java @@ -25,6 +25,7 @@ import java.util.regex.Pattern; import org.codehaus.plexus.util.SelectorUtils; +import org.vafer.jdependency.Clazz; /** * @author Jason van Zyl @@ -180,7 +181,10 @@ public boolean canRelocatePath(String path) { } if (path.endsWith(".class")) { - path = path.substring(0, path.length() - 6); + Clazz.ParsedFileName parsedFileName = Clazz.parseClassFileName(path); + if (parsedFileName != null && parsedFileName.className != null) { + path = parsedFileName.className.replace(".", "/"); + } } // Allow for annoying option of an extra / on the front of a path. See MSHADE-119; comes from diff --git a/src/main/java/org/apache/maven/plugins/shade/resource/ManifestResourceTransformer.java b/src/main/java/org/apache/maven/plugins/shade/resource/ManifestResourceTransformer.java index 9ef598b9..071bfcbf 100644 --- a/src/main/java/org/apache/maven/plugins/shade/resource/ManifestResourceTransformer.java +++ b/src/main/java/org/apache/maven/plugins/shade/resource/ManifestResourceTransformer.java @@ -112,6 +112,13 @@ public void processResource(String resource, InputStream is, List rel if (time > this.time) { this.time = time; } + } else { + // If any of the included jars is "Multi-Release" (JEP-238) then so is the end result + String multiRelease = new Manifest(is).getMainAttributes().getValue("Multi-Release"); + + if ("true".equals(multiRelease)) { + manifest.getMainAttributes().putValue("Multi-Release", "true"); + } } }