Repository: apache/maven-shade-plugin Branch: master Commit: e41b8368ed9a Files: 543 Total size: 1.2 MB Directory structure: gitextract_9k9omgyv/ ├── .asf.yaml ├── .git-blame-ignore-revs ├── .github/ │ ├── ISSUE_TEMPLATE/ │ │ ├── BUG.yml │ │ ├── FEATURE.yml │ │ └── config.yml │ ├── dependabot.yml │ ├── pull_request_template.md │ ├── release-drafter.yml │ └── workflows/ │ ├── maven-verify.yml │ ├── pr-automation.yml │ ├── release-drafter.yml │ └── stale.yml ├── .gitignore ├── Jenkinsfile ├── LICENSE ├── README.md ├── pom.xml └── src/ ├── it/ │ ├── MSHADE-321_respectDrpFlag/ │ │ ├── pom.xml │ │ ├── repo/ │ │ │ └── org/ │ │ │ └── apache/ │ │ │ └── maven/ │ │ │ └── its/ │ │ │ └── shade/ │ │ │ └── drp/ │ │ │ └── a/ │ │ │ └── 0.1/ │ │ │ ├── a-0.1.jar │ │ │ └── a-0.1.pom │ │ └── verify.groovy │ ├── mrm/ │ │ ├── repository/ │ │ │ ├── MSHADE-247/ │ │ │ │ ├── mshade-247-one-0.1-sources.jar/ │ │ │ │ │ └── org/ │ │ │ │ │ └── apache/ │ │ │ │ │ └── maven/ │ │ │ │ │ └── its/ │ │ │ │ │ └── shade/ │ │ │ │ │ └── csj/ │ │ │ │ │ └── Test.java │ │ │ │ ├── mshade-247-one-0.1.pom │ │ │ │ └── mshade-247-two-0.1.pom │ │ │ ├── artifact-includes-excludes/ │ │ │ │ ├── a-0.1.jar/ │ │ │ │ │ └── a.properties │ │ │ │ ├── a-0.1.pom │ │ │ │ ├── b-0.2.jar/ │ │ │ │ │ └── b.properties │ │ │ │ └── b-0.2.pom │ │ │ ├── dep-reduced-pom/ │ │ │ │ ├── a-0.1.pom │ │ │ │ ├── b-0.2-client.jar/ │ │ │ │ │ └── b-client.properties │ │ │ │ ├── b-0.2.pom │ │ │ │ └── c-1.pom │ │ │ ├── dep-reduced-pom-artifactset-provided-excludes/ │ │ │ │ ├── a-0.1.pom │ │ │ │ ├── b-0.1.pom │ │ │ │ ├── c-0.1.pom │ │ │ │ ├── d-0.1.pom │ │ │ │ └── e-0.1.pom │ │ │ ├── dep-reduced-pom-exclusions/ │ │ │ │ ├── a-0.1.pom │ │ │ │ ├── b-0.2-alt.jar/ │ │ │ │ │ └── b-alt.properties │ │ │ │ ├── b-0.2.pom │ │ │ │ └── c-1.pom │ │ │ ├── dep-reduced-pom-unique/ │ │ │ │ ├── a-0.1.pom │ │ │ │ ├── b-0.2.pom │ │ │ │ └── c-1.pom │ │ │ ├── dep-reduced-pom-use-base-version/ │ │ │ │ ├── a-0.1-20130115.024354-82.pom │ │ │ │ └── maven-metadata.xml │ │ │ ├── filter-artifact-contents/ │ │ │ │ ├── a-0.1.jar/ │ │ │ │ │ ├── META-INF/ │ │ │ │ │ │ └── maven/ │ │ │ │ │ │ └── org.apache.maven.its.shade.fac/ │ │ │ │ │ │ └── a/ │ │ │ │ │ │ └── pom.properties │ │ │ │ │ ├── a.properties │ │ │ │ │ └── org/ │ │ │ │ │ ├── a.properties │ │ │ │ │ └── apache/ │ │ │ │ │ ├── a.properties │ │ │ │ │ └── maven/ │ │ │ │ │ └── a.properties │ │ │ │ ├── a-0.1.pom │ │ │ │ ├── b-0.1-client.jar/ │ │ │ │ │ ├── META-INF/ │ │ │ │ │ │ └── maven/ │ │ │ │ │ │ └── org.apache.maven.its.shade.fac/ │ │ │ │ │ │ └── b/ │ │ │ │ │ │ └── pom.properties │ │ │ │ │ ├── b.properties │ │ │ │ │ └── org/ │ │ │ │ │ ├── apache/ │ │ │ │ │ │ ├── b.properties │ │ │ │ │ │ └── maven/ │ │ │ │ │ │ ├── b/ │ │ │ │ │ │ │ └── b.properties │ │ │ │ │ │ └── b.properties │ │ │ │ │ └── b.properties │ │ │ │ └── b-0.1.pom │ │ │ ├── non-runtime-scope-excluded/ │ │ │ │ ├── compile-1.0.jar/ │ │ │ │ │ └── compile.properties │ │ │ │ ├── compile-1.0.pom │ │ │ │ ├── provided-1.0.jar/ │ │ │ │ │ └── provided.properties │ │ │ │ ├── provided-1.0.pom │ │ │ │ ├── runtime-1.0.jar/ │ │ │ │ │ └── runtime.properties │ │ │ │ ├── runtime-1.0.pom │ │ │ │ ├── test-1.0.jar/ │ │ │ │ │ └── test.properties │ │ │ │ └── test-1.0.pom │ │ │ ├── plugin-descriptor-relocation/ │ │ │ │ └── comp-0.1.pom │ │ │ ├── services-resource-transformer/ │ │ │ │ ├── one-0.1.jar/ │ │ │ │ │ └── META-INF/ │ │ │ │ │ └── services/ │ │ │ │ │ └── org.apache.maven.Shade │ │ │ │ ├── one-0.1.pom │ │ │ │ ├── two-0.1.jar/ │ │ │ │ │ └── META-INF/ │ │ │ │ │ └── services/ │ │ │ │ │ └── org.apache.maven.Shade │ │ │ │ └── two-0.1.pom │ │ │ └── services-resource-transformer-with-reloc-includes-excludes/ │ │ │ ├── mshade-237-one-0.1.jar/ │ │ │ │ └── META-INF/ │ │ │ │ └── services/ │ │ │ │ └── org.apache.maven.shade │ │ │ ├── mshade-237-one-0.1.pom │ │ │ ├── mshade-237-two-0.1.jar/ │ │ │ │ └── META-INF/ │ │ │ │ └── services/ │ │ │ │ └── org.apache.maven.shade │ │ │ └── mshade-237-two-0.1.pom │ │ └── settings.xml │ └── projects/ │ ├── MSHADE-105/ │ │ ├── bundle/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ └── java/ │ │ │ └── test/ │ │ │ └── Dummy.java │ │ ├── pom.xml │ │ ├── shaded-jar/ │ │ │ └── pom.xml │ │ └── verify.bsh │ ├── MSHADE-114/ │ │ └── pom.xml │ ├── MSHADE-133/ │ │ ├── pom.xml │ │ ├── src/ │ │ │ └── main/ │ │ │ └── resources/ │ │ │ ├── logback.xml │ │ │ └── myConfig.yml │ │ └── verify.groovy │ ├── MSHADE-155/ │ │ ├── pom.xml │ │ ├── src/ │ │ │ └── main/ │ │ │ └── resources/ │ │ │ └── META-INF/ │ │ │ └── ejb-jar.xml │ │ └── verify.groovy │ ├── MSHADE-182/ │ │ ├── pom.xml │ │ ├── src/ │ │ │ └── main/ │ │ │ └── resources/ │ │ │ └── META-INF/ │ │ │ └── services/ │ │ │ └── relocateme.Service │ │ └── verify.groovy │ ├── MSHADE-183/ │ │ ├── pom.xml │ │ └── verify.bsh │ ├── MSHADE-185/ │ │ ├── invoker.properties │ │ ├── pom.xml │ │ └── verify.groovy │ ├── MSHADE-232_ResourceBundleAppendingTransformer/ │ │ ├── invoker.properties │ │ ├── one/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ └── resources/ │ │ │ └── org/ │ │ │ └── apache/ │ │ │ └── maven/ │ │ │ └── plugins/ │ │ │ └── shade/ │ │ │ └── its/ │ │ │ ├── Message.properties │ │ │ └── Message_nl.properties │ │ ├── pom.xml │ │ ├── two/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ └── resources/ │ │ │ └── org/ │ │ │ └── apache/ │ │ │ └── maven/ │ │ │ └── plugins/ │ │ │ └── shade/ │ │ │ └── its/ │ │ │ ├── Message.properties │ │ │ └── Message_nl.properties │ │ └── verify.groovy │ ├── MSHADE-239_finalName-attachments/ │ │ ├── pom.xml │ │ └── verify.groovy │ ├── MSHADE-240_reloc-mavenfiles/ │ │ ├── pom.xml │ │ └── verify.groovy │ ├── MSHADE-247/ │ │ └── pom.xml │ ├── MSHADE-258_module_relocation/ │ │ ├── pom.xml │ │ └── verify.groovy │ ├── MSHADE-260-reloc-serialized-lambda/ │ │ ├── README.txt │ │ ├── invoker.properties │ │ ├── pom.xml │ │ ├── src/ │ │ │ └── main/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── apache/ │ │ │ └── maven/ │ │ │ └── its/ │ │ │ └── shade/ │ │ │ └── reloc/ │ │ │ └── lambda/ │ │ │ ├── DataHolder.java │ │ │ ├── Main.java │ │ │ ├── MapFunction.java │ │ │ └── Processor.java │ │ └── verify.groovy │ ├── MSHADE-284_shadeTestJar/ │ │ ├── api/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── Api.java │ │ │ │ └── resources/ │ │ │ │ └── api-resource.txt │ │ │ └── test/ │ │ │ ├── java/ │ │ │ │ └── ApiTest.java │ │ │ └── resources/ │ │ │ └── api-test-resource.txt │ │ ├── impl/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── Impl.java │ │ │ │ └── resources/ │ │ │ │ └── impl-resource.txt │ │ │ └── test/ │ │ │ ├── java/ │ │ │ │ └── ImplTest.java │ │ │ └── resources/ │ │ │ └── impl-test-resource.txt │ │ ├── pom.xml │ │ ├── uber/ │ │ │ └── pom.xml │ │ └── verify.groovy │ ├── MSHADE-285_createTestSourcesJar/ │ │ ├── api/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ └── java/ │ │ │ │ └── Api.java │ │ │ └── test/ │ │ │ └── java/ │ │ │ └── ApiTest.java │ │ ├── impl/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ └── java/ │ │ │ │ └── Impl.java │ │ │ └── test/ │ │ │ └── java/ │ │ │ └── ImplTest.java │ │ ├── pom.xml │ │ ├── uber/ │ │ │ └── pom.xml │ │ └── verify.groovy │ ├── MSHADE-313_minimized-services/ │ │ ├── dependency-service/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ ├── DependencyReferencedClass.java │ │ │ │ ├── DependencyServiceClass.java │ │ │ │ ├── DependencyServiceInterface.java │ │ │ │ └── DependencyUnreferencedClass.java │ │ │ └── resources/ │ │ │ └── META-INF/ │ │ │ └── services/ │ │ │ └── DependencyServiceInterface │ │ ├── invoker.properties │ │ ├── pom.xml │ │ ├── test/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ └── java/ │ │ │ └── Main.java │ │ ├── unused-service/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ ├── UnusedServiceClass.java │ │ │ │ └── UnusedServiceInterface.java │ │ │ └── resources/ │ │ │ └── META-INF/ │ │ │ └── services/ │ │ │ └── UnusedServiceInterface │ │ ├── used-service/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ ├── SomeReferencedClass.java │ │ │ │ ├── SomeServiceClass.java │ │ │ │ ├── SomeServiceInterface.java │ │ │ │ └── SomeUnreferencedClass.java │ │ │ └── resources/ │ │ │ └── META-INF/ │ │ │ └── services/ │ │ │ └── SomeServiceInterface │ │ └── verify.bsh │ ├── MSHADE-316/ │ │ ├── dependency/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ └── java/ │ │ │ ├── SomeUnusedClass.java │ │ │ ├── SomeUsedClass.java │ │ │ └── x/ │ │ │ └── y/ │ │ │ └── z/ │ │ │ ├── AnotherExemptedClass.java │ │ │ ├── SomeDependencyOfExemptedClass.java │ │ │ └── SomeExemptedClass.java │ │ ├── invoker.properties │ │ ├── pom.xml │ │ ├── test/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ └── java/ │ │ │ └── Main.java │ │ └── verify.bsh │ ├── MSHADE-340_shadedTestJarArtifactAttached/ │ │ ├── api/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ └── java/ │ │ │ │ └── Api.java │ │ │ └── test/ │ │ │ └── java/ │ │ │ └── ApiTest.java │ │ ├── impl/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ └── java/ │ │ │ │ └── Impl.java │ │ │ └── test/ │ │ │ └── java/ │ │ │ └── ImplTest.java │ │ ├── pom.xml │ │ ├── uber/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ └── java/ │ │ │ │ └── Uber.java │ │ │ └── test/ │ │ │ └── java/ │ │ │ └── UberTest.java │ │ ├── uber-user/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ └── java/ │ │ │ │ └── UberUser.java │ │ │ └── test/ │ │ │ └── java/ │ │ │ └── UberUserTest.java │ │ └── verify.groovy │ ├── MSHADE-351/ │ │ ├── pom.xml │ │ └── verify.bsh │ ├── MSHADE-36-inject-dep-reduced-pom-in-final/ │ │ ├── invoker.properties │ │ ├── pom.xml │ │ ├── src/ │ │ │ └── main/ │ │ │ └── java/ │ │ │ └── com/ │ │ │ └── example/ │ │ │ └── Main.java │ │ └── verify.bsh │ ├── MSHADE-363_old-Transformer/ │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ └── resources/ │ │ └── Message.properties │ ├── MSHADE-363_old-plugin/ │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ └── resources/ │ │ └── Message.properties │ ├── MSHADE-373/ │ │ ├── pom.xml │ │ └── verify.bsh │ ├── MSHADE-382_skip_execution/ │ │ ├── invoker.properties │ │ ├── pom.xml │ │ └── verify.groovy │ ├── MSHADE-390-sisu-index/ │ │ ├── invoker.properties │ │ ├── one/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── apache/ │ │ │ │ └── one/ │ │ │ │ └── One.java │ │ │ └── resources/ │ │ │ └── META-INF/ │ │ │ └── sisu/ │ │ │ └── javax.inject.Named │ │ ├── pom.xml │ │ ├── two/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── apache/ │ │ │ │ └── two/ │ │ │ │ └── Two.java │ │ │ └── resources/ │ │ │ └── META-INF/ │ │ │ └── sisu/ │ │ │ └── javax.inject.Named │ │ └── verify.groovy │ ├── MSHADE-391_noRelocationKeepOriginalClasses/ │ │ ├── pom.xml │ │ └── verify.groovy │ ├── MSHADE-400_self-minimized-services/ │ │ ├── invoker.properties │ │ ├── pom.xml │ │ ├── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── acme/ │ │ │ │ ├── Application.java │ │ │ │ ├── UnusedClass.java │ │ │ │ ├── UnusedService.java │ │ │ │ ├── UnusedServiceImplA.java │ │ │ │ ├── UnusedServiceImplB.java │ │ │ │ ├── UsedClass.java │ │ │ │ ├── UsedService.java │ │ │ │ ├── UsedServiceUnusedImpl.java │ │ │ │ └── UsedServiceUsedImpl.java │ │ │ └── resources/ │ │ │ └── META-INF/ │ │ │ └── services/ │ │ │ ├── org.acme.UnusedService │ │ │ └── org.acme.UsedService │ │ └── verify.bsh │ ├── MSHADE-413-parallel/ │ │ ├── invoker.properties │ │ ├── p1/ │ │ │ └── pom.xml │ │ ├── p2/ │ │ │ └── pom.xml │ │ └── pom.xml │ ├── MSHADE-420/ │ │ ├── invoker.properties │ │ ├── pom.xml │ │ ├── verify.groovy │ │ └── zipdetails.txt │ ├── MSHADE-462/ │ │ ├── all/ │ │ │ └── pom.xml │ │ ├── invoker.properties │ │ ├── one/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── apache/ │ │ │ └── one/ │ │ │ └── One.java │ │ └── pom.xml │ ├── MSHADE-467_parallel-dependency-reduced-pom/ │ │ ├── invoker.properties │ │ ├── pom.xml │ │ ├── shadeMT1/ │ │ │ └── pom.xml │ │ ├── shadeMT2/ │ │ │ └── pom.xml │ │ ├── shadeMT3/ │ │ │ └── pom.xml │ │ ├── shadeMT4/ │ │ │ └── pom.xml │ │ └── verify.groovy │ ├── artifact-includes-excludes/ │ │ ├── pom.xml │ │ └── verify.bsh │ ├── attach-after-lifecycle-fork/ │ │ ├── invoker.properties │ │ ├── pom.xml │ │ ├── setup.bsh │ │ └── verify.bsh │ ├── attached-artifact-type/ │ │ ├── consumer/ │ │ │ └── pom.xml │ │ ├── invoker.properties │ │ ├── pom.xml │ │ └── shade/ │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ └── resources/ │ │ └── META-INF/ │ │ └── ejb-jar.xml │ ├── component-descriptor-relocation/ │ │ ├── app/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ ├── Main.java │ │ │ │ └── org/ │ │ │ │ └── apache/ │ │ │ │ └── maven/ │ │ │ │ └── test/ │ │ │ │ └── TestComponent.java │ │ │ └── resources/ │ │ │ └── META-INF/ │ │ │ └── plexus/ │ │ │ └── components.xml │ │ ├── lib/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── apache/ │ │ │ │ └── maven/ │ │ │ │ └── component/ │ │ │ │ ├── api/ │ │ │ │ │ └── Component.java │ │ │ │ └── impl/ │ │ │ │ └── DefaultComponent.java │ │ │ └── resources/ │ │ │ └── META-INF/ │ │ │ └── plexus/ │ │ │ └── components.xml │ │ └── pom.xml │ ├── dep-reduced-pom/ │ │ ├── pom.xml │ │ └── verify.groovy │ ├── dep-reduced-pom-artifactset-provided-excludes/ │ │ ├── pom.xml │ │ └── verify.groovy │ ├── dep-reduced-pom-exclusions/ │ │ ├── invoker.properties │ │ ├── pom.xml │ │ └── verify.groovy │ ├── dep-reduced-pom-relocated-result/ │ │ ├── child/ │ │ │ └── pom.xml │ │ ├── invoker.properties │ │ └── pom.xml │ ├── dep-reduced-pom-unique/ │ │ ├── pom.xml │ │ └── verify.groovy │ ├── dep-reduced-pom-use-base-version/ │ │ ├── pom.xml │ │ └── verify.groovy │ ├── dep-reduced-pom-with-local-parent/ │ │ ├── child/ │ │ │ └── pom.xml │ │ ├── invoker.properties │ │ └── pom.xml │ ├── duplicate-classes-with-reloc/ │ │ ├── app/ │ │ │ └── pom.xml │ │ ├── libs/ │ │ │ ├── a-0.1.pom │ │ │ ├── b-0.1.pom │ │ │ └── src/ │ │ │ └── main/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── apache/ │ │ │ └── maven/ │ │ │ └── its/ │ │ │ └── shade/ │ │ │ ├── MyInterface.java │ │ │ └── impl/ │ │ │ └── MyImpl.java │ │ └── pom.xml │ ├── duplicate-classes-without-reloc/ │ │ ├── app/ │ │ │ └── pom.xml │ │ ├── libs/ │ │ │ ├── a-0.1.pom │ │ │ ├── b-0.1.pom │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── apache/ │ │ │ │ └── maven/ │ │ │ │ └── its/ │ │ │ │ └── shade/ │ │ │ │ ├── MyInterface.java │ │ │ │ └── impl/ │ │ │ │ └── MyImpl.java │ │ │ └── resources/ │ │ │ └── some-ordinary-resource.txt │ │ └── pom.xml │ ├── empty-apache-notice-transform/ │ │ └── pom.xml │ ├── empty-relocation-pattern/ │ │ ├── invoker.properties │ │ └── pom.xml │ ├── empty-relocation-shaded-pattern/ │ │ └── pom.xml │ ├── extrajar/ │ │ ├── pom.xml │ │ └── verify.bsh │ ├── extrajar-missing-file/ │ │ ├── invoker.properties │ │ └── pom.xml │ ├── filter-artifact-contents/ │ │ ├── pom.xml │ │ └── verify.bsh │ ├── finalNameBuild/ │ │ ├── invoker.properties │ │ ├── pom.xml │ │ ├── setup.bsh │ │ ├── src/ │ │ │ └── main/ │ │ │ └── resources/ │ │ │ └── META-INF/ │ │ │ └── ejb-jar.xml │ │ └── verify.bsh │ ├── finalNameBuild-attached/ │ │ ├── invoker.properties │ │ ├── pom.xml │ │ ├── setup.bsh │ │ ├── src/ │ │ │ └── main/ │ │ │ └── resources/ │ │ │ └── META-INF/ │ │ │ └── ejb-jar.xml │ │ └── verify.bsh │ ├── finalNameShade/ │ │ ├── invoker.properties │ │ ├── pom.xml │ │ ├── setup.bsh │ │ ├── src/ │ │ │ └── main/ │ │ │ └── resources/ │ │ │ └── META-INF/ │ │ │ └── ejb-jar.xml │ │ └── verify.bsh │ ├── finalNameShade-attached/ │ │ ├── invoker.properties │ │ ├── pom.xml │ │ ├── setup.bsh │ │ ├── src/ │ │ │ └── main/ │ │ │ └── resources/ │ │ │ └── META-INF/ │ │ │ └── ejb-jar.xml │ │ └── verify.bsh │ ├── implicit-inclusion-of-project-artifact/ │ │ ├── pom.xml │ │ ├── src/ │ │ │ └── main/ │ │ │ └── java/ │ │ │ └── Passed.java │ │ └── verify.bsh │ ├── manifest-retained/ │ │ ├── pom.xml │ │ └── verify.bsh │ ├── manifest-transformed/ │ │ ├── pom.xml │ │ └── verify.bsh │ ├── mini-jar/ │ │ ├── invoker.properties │ │ ├── pom.xml │ │ ├── src/ │ │ │ └── main/ │ │ │ └── java/ │ │ │ └── Main.java │ │ └── verify.bsh │ ├── mini-jar-jdk11+/ │ │ ├── invoker.properties │ │ ├── pom.xml │ │ ├── src/ │ │ │ └── main/ │ │ │ └── java/ │ │ │ └── Main.java │ │ └── verify.bsh │ ├── mini-jar-malformed-dependencies/ │ │ ├── invoker.properties │ │ └── pom.xml │ ├── mini-jar-package-info/ │ │ ├── invoker.properties │ │ ├── jar-with-package-info/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── apache/ │ │ │ └── maven/ │ │ │ └── it/ │ │ │ └── pi/ │ │ │ ├── HaveOneClass.java │ │ │ ├── TestPackageAnnotation.java │ │ │ └── package-info.java │ │ ├── pom.xml │ │ ├── test/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── apache/ │ │ │ └── maven/ │ │ │ └── it/ │ │ │ └── pi/ │ │ │ └── Main.java │ │ └── verify.bsh │ ├── mini-jar-respect-includes/ │ │ ├── invoker.properties │ │ ├── pom.xml │ │ ├── src/ │ │ │ └── main/ │ │ │ └── java/ │ │ │ └── Main.java │ │ └── verify.bsh │ ├── mshade-123/ │ │ ├── assembly.xml │ │ ├── invoker.properties │ │ ├── pom.xml │ │ └── sample.txt │ ├── non-runtime-scope-excluded/ │ │ ├── pom.xml │ │ ├── system.jar │ │ └── verify.bsh │ ├── plugin-descriptor-relocation/ │ │ ├── app/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── apache/ │ │ │ └── maven/ │ │ │ └── test/ │ │ │ ├── Entry.java │ │ │ └── TestMojo.java │ │ ├── lib/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── apache/ │ │ │ │ └── maven/ │ │ │ │ └── component/ │ │ │ │ ├── api/ │ │ │ │ │ └── Component.java │ │ │ │ └── impl/ │ │ │ │ └── DefaultComponent.java │ │ │ └── resources/ │ │ │ └── META-INF/ │ │ │ └── plexus/ │ │ │ └── components.xml │ │ ├── pom.xml │ │ └── verify.groovy │ ├── pom-packaging/ │ │ ├── pom.xml │ │ └── verify.bsh │ ├── project-with-reactors-included/ │ │ ├── invoker.properties │ │ ├── one/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ └── java/ │ │ │ │ └── org/ │ │ │ │ └── apache/ │ │ │ │ └── maven/ │ │ │ │ └── plugins/ │ │ │ │ └── shade/ │ │ │ │ └── its/ │ │ │ │ └── one/ │ │ │ │ ├── App.java │ │ │ │ └── AppOne.java │ │ │ └── test/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── apache/ │ │ │ └── maven/ │ │ │ └── plugins/ │ │ │ └── shade/ │ │ │ └── its/ │ │ │ └── one/ │ │ │ └── AppTest.java │ │ ├── pom.xml │ │ ├── two/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ └── java/ │ │ │ │ └── org/ │ │ │ │ └── apache/ │ │ │ │ └── maven/ │ │ │ │ └── plugins/ │ │ │ │ └── shade/ │ │ │ │ └── its/ │ │ │ │ └── two/ │ │ │ │ └── App.java │ │ │ └── test/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── apache/ │ │ │ └── maven/ │ │ │ └── plugins/ │ │ │ └── shade/ │ │ │ └── its/ │ │ │ └── two/ │ │ │ └── AppTest.java │ │ └── verify.bsh │ ├── reloc-abs-resource-path/ │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── Main.java │ │ └── resources/ │ │ └── org/ │ │ └── apache/ │ │ └── maven/ │ │ └── from/ │ │ └── test.properties │ ├── reloc-abs-resource-path-exclude/ │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── Main.java │ │ └── resources/ │ │ └── org/ │ │ └── apache/ │ │ └── maven/ │ │ └── from/ │ │ ├── a/ │ │ │ └── test.properties │ │ └── b/ │ │ └── test.properties │ ├── reloc-and-mini/ │ │ ├── invoker.properties │ │ ├── pom.xml │ │ ├── src/ │ │ │ └── main/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── apache/ │ │ │ └── maven/ │ │ │ └── plugins/ │ │ │ └── shade/ │ │ │ └── its/ │ │ │ └── App.java │ │ └── verify.bsh │ ├── reloc-anno/ │ │ ├── invoker.properties │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ └── java/ │ │ ├── Main.java │ │ └── relocated/ │ │ └── MyAnno.java │ ├── reloc-class-from-string-pool/ │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ └── java/ │ │ ├── Main.java │ │ └── relocated/ │ │ └── RelocatedClass.java │ ├── reloc-enum-ref-from-anno/ │ │ ├── invoker.properties │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ └── java/ │ │ ├── Main.java │ │ ├── MyAnno.java │ │ └── relocated/ │ │ └── MyEnum.java │ ├── reloc-includes-excludes/ │ │ ├── pom.xml │ │ └── verify.bsh │ ├── rerun-with-reloc/ │ │ ├── invoker.properties │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── MyInterface.java │ │ └── resources/ │ │ └── some-ordinary-resource.txt │ ├── rerun-without-reloc/ │ │ ├── invoker.properties │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── MyInterface.java │ │ └── resources/ │ │ └── some-ordinary-resource.txt │ ├── services-resource-transformer/ │ │ ├── pom.xml │ │ └── verify.bsh │ ├── services-resource-transformer-with-reloc-includes-excludes/ │ │ ├── pom.xml │ │ └── verify.bsh │ ├── setup-parent/ │ │ └── pom.xml │ ├── shadePomDependency/ │ │ ├── pom.xml │ │ ├── pomDependency/ │ │ │ └── pom.xml │ │ ├── shadingModule/ │ │ │ └── pom.xml │ │ └── testModule/ │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ └── java/ │ │ └── ShadedClassUsage.java │ ├── shading-with-java-8-sources/ │ │ ├── invoker.properties │ │ ├── pom.xml │ │ ├── src/ │ │ │ └── main/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── apache/ │ │ │ └── maven/ │ │ │ └── plugins/ │ │ │ └── shade/ │ │ │ └── its/ │ │ │ └── App.java │ │ └── verify.groovy │ ├── shading-with-release-sources/ │ │ ├── invoker.properties │ │ ├── pom.xml │ │ ├── src/ │ │ │ └── main/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── apache/ │ │ │ └── maven/ │ │ │ └── plugins/ │ │ │ └── shade/ │ │ │ └── its/ │ │ │ └── App.java │ │ └── verify.groovy │ ├── users-shader-impl/ │ │ ├── invoker.properties │ │ ├── pom.xml │ │ ├── src/ │ │ │ ├── main/ │ │ │ │ └── java/ │ │ │ │ └── org/ │ │ │ │ └── apache/ │ │ │ │ └── maven/ │ │ │ │ └── plugins/ │ │ │ │ └── shade/ │ │ │ │ └── its/ │ │ │ │ └── App.java │ │ │ └── test/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── apache/ │ │ │ └── maven/ │ │ │ └── plugins/ │ │ │ └── shade/ │ │ │ └── its/ │ │ │ └── AppTest.java │ │ └── verify.groovy │ └── xml-transformer-ignores-dtd/ │ ├── pom.xml │ ├── src/ │ │ └── main/ │ │ └── resources/ │ │ └── test.xml │ └── verify.bsh ├── main/ │ └── java/ │ └── org/ │ └── apache/ │ └── maven/ │ └── plugins/ │ └── shade/ │ ├── DefaultShader.java │ ├── ShadeRequest.java │ ├── Shader.java │ ├── ShadingResult.java │ ├── filter/ │ │ ├── Filter.java │ │ ├── MinijarFilter.java │ │ └── SimpleFilter.java │ ├── mojo/ │ │ ├── ArchiveFilter.java │ │ ├── ArtifactId.java │ │ ├── ArtifactSelector.java │ │ ├── ArtifactSet.java │ │ ├── PackageRelocation.java │ │ ├── RelativizePath.java │ │ └── ShadeMojo.java │ ├── pom/ │ │ ├── Counter.java │ │ ├── MavenJDOMWriter.java │ │ └── PomWriter.java │ ├── relocation/ │ │ ├── Relocator.java │ │ ├── SerializedLambdaRelocator.java │ │ └── SimpleRelocator.java │ └── resource/ │ ├── AbstractCompatibilityTransformer.java │ ├── ApacheLicenseResourceTransformer.java │ ├── ApacheNoticeResourceTransformer.java │ ├── AppendingTransformer.java │ ├── ComponentsXmlResourceTransformer.java │ ├── DontIncludeResourceTransformer.java │ ├── GroovyResourceTransformer.java │ ├── IncludeResourceTransformer.java │ ├── ManifestResourceTransformer.java │ ├── PluginXmlResourceTransformer.java │ ├── ReproducibleResourceTransformer.java │ ├── ResourceBundleAppendingTransformer.java │ ├── ResourceTransformer.java │ ├── ServicesResourceTransformer.java │ ├── SisuIndexResourceTransformer.java │ ├── UseDependencyReducedPom.java │ ├── XmlAppendingTransformer.java │ └── properties/ │ ├── MicroprofileConfigTransformer.java │ ├── OpenWebBeansPropertiesTransformer.java │ ├── PropertiesTransformer.java │ ├── SortedProperties.java │ └── io/ │ ├── NoCloseOutputStream.java │ └── SkipPropertiesDateLineWriter.java ├── site/ │ ├── apt/ │ │ ├── examples/ │ │ │ ├── attached-artifact.apt.vm │ │ │ ├── class-relocation.apt.vm │ │ │ ├── executable-jar.apt.vm │ │ │ ├── includes-excludes.apt.vm │ │ │ ├── resource-transformers.apt.vm │ │ │ └── use-shader-other-impl.apt.vm │ │ ├── index.apt.vm │ │ └── usage.apt.vm │ ├── fml/ │ │ └── faq.fml │ ├── resources/ │ │ └── download.cgi │ ├── site.xml │ └── xdoc/ │ └── download.xml.vm └── test/ ├── jars/ │ ├── plexus-utils-1.4.1.jar │ ├── test-artifact-1.0-SNAPSHOT.jar │ └── test-project-1.0-SNAPSHOT.jar ├── java/ │ └── org/ │ └── apache/ │ └── maven/ │ └── plugins/ │ └── shade/ │ ├── DefaultShaderTest.java │ ├── MockShader.java │ ├── custom/ │ │ └── CustomReproducibleResourceTransformer.java │ ├── filter/ │ │ ├── MinijarFilterTest.java │ │ └── SimpleFilterTest.java │ ├── mojo/ │ │ ├── ArtifactIdTest.java │ │ ├── ArtifactSelectorTest.java │ │ ├── RelativizePathTest.java │ │ └── ShadeMojoTest.java │ ├── relocation/ │ │ ├── SimpleRelocatorParameterTest.java │ │ └── SimpleRelocatorTest.java │ └── resource/ │ ├── ApacheLicenseResourceTransformerTest.java │ ├── ApacheNoticeResourceTransformerTest.java │ ├── AppendingTransformerTest.java │ ├── ComponentsXmlResourceTransformerTest.java │ ├── GroovyResourceTransformerTest.java │ ├── ManifestResourceTransformerTest.java │ ├── ReproducibleResourceTransformer.java │ ├── ResourceBundleAppendingTransformerTest.java │ ├── ServiceResourceTransformerTest.java │ ├── XmlAppendingTransformerTest.java │ ├── properties/ │ │ └── PropertiesTransformerTest.java │ └── rule/ │ └── TransformerTesterRule.java ├── projects/ │ ├── default-config-project/ │ │ └── pom.xml │ ├── no-relocation-project/ │ │ └── pom.xml │ ├── pom.xml │ ├── shaded-attached-project/ │ │ └── pom.xml │ ├── shaded-project/ │ │ └── pom.xml │ ├── shaded-renamed-project/ │ │ └── pom.xml │ ├── test-artifact/ │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ └── java/ │ │ └── org/ │ │ └── apache/ │ │ └── maven/ │ │ └── plugins/ │ │ └── shade/ │ │ └── Lib.java │ └── test-project/ │ ├── pom.xml │ └── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── apache/ │ │ │ └── maven/ │ │ │ └── plugins/ │ │ │ └── shade/ │ │ │ └── App.java │ │ └── resources/ │ │ └── META-INF/ │ │ └── plexus/ │ │ └── components.xml │ └── test/ │ └── java/ │ └── org/ │ └── apache/ │ └── maven/ │ └── plugins/ │ └── shade/ │ └── AppTest.java └── resources/ ├── components-1.xml ├── components-2.xml └── components-expected.xml ================================================ FILE CONTENTS ================================================ ================================================ FILE: .asf.yaml ================================================ # # 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. # # see https://s.apache.org/asfyaml github: description: "Apache Maven Shade Plugin" homepage: https://maven.apache.org/plugins/maven-shade-plugin/ labels: - java - build-management - maven-plugins - maven-shade-plugin - maven enabled_merge_buttons: squash: true merge: false rebase: true autolink_jira: - MSHADE protected_branches: master: {} pull_requests: del_branch_on_merge: true features: issues: true notifications: commits: commits@maven.apache.org issues: issues@maven.apache.org pullrequests: issues@maven.apache.org ================================================ FILE: .git-blame-ignore-revs ================================================ # # 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. # # Change maven code style 80d78cc62109585f14659d509211a14d36867a78 ================================================ FILE: .github/ISSUE_TEMPLATE/BUG.yml ================================================ # # 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. # # https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema name: Bug Report description: File a bug report labels: ["bug"] body: - type: markdown attributes: value: | Thanks for taking the time to fill out this bug report. Simple fixes in single PRs do not require issues. **Do you use the latest project version?** - type: input id: version attributes: label: Affected version validations: required: true - type: textarea id: message attributes: label: Bug description validations: required: true ================================================ FILE: .github/ISSUE_TEMPLATE/FEATURE.yml ================================================ # # 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. # # https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema name: Feature request description: File a proposal for new feature, improvement labels: ["enhancement"] body: - type: markdown attributes: value: | Thanks for taking the time to fill out this new feature, improvement proposal. - type: textarea id: message attributes: label: New feature, improvement proposal validations: required: true ================================================ FILE: .github/ISSUE_TEMPLATE/config.yml ================================================ # # 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. # # https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/configuring-issue-templates-for-your-repository#configuring-the-template-chooser blank_issues_enabled: false contact_links: - name: Project Mailing Lists url: https://maven.apache.org/mailing-lists.html about: Please ask a question or discuss here ================================================ FILE: .github/dependabot.yml ================================================ # # 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. # # Please see the documentation for all configuration options: # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates # version: 2 updates: - package-ecosystem: maven directory: "/" schedule: interval: daily time: '04:00' ignore: # ignore Java 8+ dependencies - dependency-name: org.mockito:mockito-core versions: - ">= 3.0" - dependency-name: org.apache.commons:commons-lang3 versions: - ">= 3.9" - dependency-name: commons-io:commons-io versions: - ">= 2.7" # Ignore Maven 3.2.1+ - dependency-name: org.apache.maven.plugin-testing:maven-plugin-testing-tools versions: - ">=3.2.0" - package-ecosystem: "github-actions" directory: "/" schedule: interval: "daily" time: '04:00' ================================================ FILE: .github/pull_request_template.md ================================================ Following this checklist to help us incorporate your contribution quickly and easily: - [ ] Make sure there is a [JIRA issue](https://issues.apache.org/jira/browse/MSHADE) filed for the change (usually before you start working on it). Trivial changes like typos do not require a JIRA issue. Your pull request should address just this issue, without pulling in other changes. - [ ] Each commit in the pull request should have a meaningful subject line and body. - [ ] Format the pull request title like `[MSHADE-XXX] - Fixes bug in ApproximateQuantiles`, where you replace `MSHADE-XXX` with the appropriate JIRA issue. Best practice is to use the JIRA issue title in the pull request title and in the first line of the commit message. - [ ] Write a pull request description that is detailed enough to understand what the pull request does, how, and why. - [ ] Run `mvn clean verify` to make sure basic checks pass. A more thorough check will be performed on your pull request automatically. - [ ] You have run the integration tests successfully (`mvn -Prun-its clean verify`). If your pull request is about ~20 lines of code you don't need to sign an [Individual Contributor License Agreement](https://www.apache.org/licenses/icla.pdf) if you are unsure please ask on the developers list. To make clear that you license your contribution under the [Apache License Version 2.0, January 2004](http://www.apache.org/licenses/LICENSE-2.0) you have to acknowledge this by using the following check-box. - [ ] I hereby declare this contribution to be licenced under the [Apache License Version 2.0, January 2004](http://www.apache.org/licenses/LICENSE-2.0) - [ ] In any other case, please file an [Apache Individual Contributor License Agreement](https://www.apache.org/licenses/icla.pdf). ================================================ FILE: .github/release-drafter.yml ================================================ # 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. _extends: maven-gh-actions-shared tag-template: maven-shade-plugin-$RESOLVED_VERSION ================================================ FILE: .github/workflows/maven-verify.yml ================================================ # 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. name: Verify on: push: pull_request: jobs: build: name: Verify uses: apache/maven-gh-actions-shared/.github/workflows/maven-verify.yml@v4 ================================================ FILE: .github/workflows/pr-automation.yml ================================================ # 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. name: PR Automation on: pull_request_target: types: - closed jobs: pr-automation: name: PR Automation uses: apache/maven-gh-actions-shared/.github/workflows/pr-automation.yml@v4 ================================================ FILE: .github/workflows/release-drafter.yml ================================================ # 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. name: Release Drafter on: push: branches: - master jobs: update_release_draft: uses: apache/maven-gh-actions-shared/.github/workflows/release-drafter.yml@v4 ================================================ FILE: .github/workflows/stale.yml ================================================ # 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. name: Stale on: schedule: - cron: '27 2 * * *' issue_comment: types: [ 'created' ] jobs: stale: uses: 'apache/maven-gh-actions-shared/.github/workflows/stale.yml@v4' ================================================ FILE: .gitignore ================================================ target/ .project .classpath .settings/ .svn/ bin/ # Intellij *.ipr *.iml .idea out/ .DS_Store /bootstrap /dependencies.xml .java-version .checkstyle ================================================ FILE: Jenkinsfile ================================================ /** * 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. */ asfMavenTlpPlgnBuild() ================================================ FILE: LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed 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. ================================================ FILE: README.md ================================================ Contributing to [Apache Maven Shade Plugin](https://maven.apache.org/plugins/maven-shade-plugin/) ====================== [![Apache License, Version 2.0, January 2004](https://img.shields.io/github/license/apache/maven.svg?label=License)][license] [![Maven Central](https://img.shields.io/maven-central/v/org.apache.maven.plugins/maven-shade-plugin.svg?label=Maven%20Central)](https://search.maven.org/artifact/org.apache.maven.plugins/maven-shade-plugin) [![Reproducible Builds](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/jvm-repo-rebuild/reproducible-central/master/content/org/apache/maven/plugins/maven-shade-plugin/badge.json)](https://github.com/jvm-repo-rebuild/reproducible-central/blob/master/content/org/apache/maven/plugins/maven-shade-plugin/README.md) [![Jenkins Status](https://img.shields.io/jenkins/s/https/ci-maven.apache.org/job/Maven/job/maven-box/job/maven-shade-plugin/job/master.svg?)][build] [![Jenkins tests](https://img.shields.io/jenkins/t/https/ci-maven.apache.org/job/Maven/job/maven-box/job/maven-shade-plugin/job/master.svg?)][test-results] You have found a bug, or you have an idea for a cool new feature? Contributing code is a great way to give something back to the open source community. Before you dig right into the code, there are a few guidelines that we need contributors to follow so that we can have a chance of keeping on top of things. Getting Started --------------- + Make sure you have a [GitHub account](https://github.com/signup/free). + If you're planning to implement a new feature, it makes sense to discuss your changes on the [dev list][ml-list] first. This way you can make sure you're not wasting your time on something that isn't considered to be in Apache Maven's scope. + Submit a ticket for your issue, assuming one does not already exist. + Clearly describe the issue, including steps to reproduce when it is a bug. + Make sure you fill in the earliest version that you know has the issue. + Fork the repository on GitHub. Making and Submitting Changes -------------- We accept Pull Requests via GitHub. The [developer mailing list][ml-list] is the main channel of communication for contributors. There are some guidelines which will make applying PRs easier for us: + Create a topic branch from where you want to base your work (this is usually the master branch). Push your changes to a topic branch in your fork of the repository. + Make commits of logical units. + Respect the original code style: by using the same [codestyle][code-style], patches should only highlight the actual difference, not being disturbed by any formatting issues: + Only use spaces for indentation. + Create minimal diffs - disable on save actions like reformat source code or organize imports. If you feel the source code should be reformatted, create a separate PR for this change. + Check for unnecessary whitespace with `git diff --check` before committing. + Make sure you have added the necessary tests (JUnit/IT) for your changes. + Run all the tests with `mvn -Prun-its verify` to assure nothing else was accidentally broken. + Submit a pull request to the repository in the Apache organization. If you plan to contribute on a regular basis, please consider filing a [contributor license agreement][cla]. Developer Tips -------------- If your machine is sufficiently powerful, and you want to parallelize the IT execution to validate the build before a PR you can set the concurrency in `MAVEN_OPTS`: ```` MAVEN_OPTS=-Dinvoker.parallelThreads=2 mvn verify -Prun-its ```` You can also run a single IT test using: ```` mvn verify -Prun-its -Dinvoker.test=myitproject ```` Additional Resources -------------------- + [Contributing patches](https://maven.apache.org/guides/development/guide-maven-development.html#Creating_and_submitting_a_patch) + [Contributor License Agreement][cla] + [General GitHub documentation](https://help.github.com/) + [GitHub pull request documentation](https://help.github.com/send-pull-requests/) + [Apache Maven X Account](https://x.com/ASFMavenProject) + [Apache Maven Bluesky Account](https://bsky.app/profile/maven.apache.org) + [Apache Maven Mastodon Account](https://mastodon.social/deck/@ASFMavenProject@fosstodon.org) + [Slack channel for regular contributors](https://infra.apache.org/slack.html) [license]: https://www.apache.org/licenses/LICENSE-2.0 [ml-list]: https://maven.apache.org/mailing-lists.html [code-style]: https://maven.apache.org/developers/conventions/code.html [cla]: https://www.apache.org/licenses/#clas [maven-wiki]: https://cwiki.apache.org/confluence/display/MAVEN/Index [test-results]: https://ci-maven.apache.org/job/Maven/job/maven-box/job/maven-shade-plugin/job/master/lastCompletedBuild/testReport/ [build]: https://ci-maven.apache.org/job/Maven/job/maven-box/job/maven-shade-plugin/job/master/ ================================================ FILE: pom.xml ================================================ 4.0.0 org.apache.maven.plugins maven-plugins 47 maven-shade-plugin 3.6.3-SNAPSHOT maven-plugin Apache Maven Shade Plugin Repackages the project classes together with their dependencies into a single uber-jar, optionally renaming classes or removing unused classes. Trask Stalnaker Anthony Dahanne Fabiano Cipriano de Oliveira Markus Karg Torsten Curdt 3.6.3 scm:git:https://github.com/apache/maven-shade-plugin.git scm:git:https://github.com/apache/maven-shade-plugin.git HEAD https://github.com/apache/maven-shade-plugin/tree/${project.scm.tag} GitHub https://github.com/apache/maven-shade-plugin/issues/ Jenkins https://ci-maven.apache.org/job/Maven/job/maven-box/job/maven-shade-plugin/ apache.website scm:svn:https://svn.apache.org/repos/asf/maven/website/components/${maven.site.path} 3.9.15 8 ${project.version} 9.9.1 1.7.36 2026-03-02T10:52:20Z junit junit 4.13.2 org.hamcrest hamcrest 3.0 org.hamcrest hamcrest-core 3.0 org.ow2.asm asm ${asmVersion} org.ow2.asm asm-commons ${asmVersion} org.jdom jdom2 2.0.6.1 org.vafer jdependency 2.15 org.codehaus.plexus plexus-utils 3.6.1 org.apache.maven maven-plugin-api ${mavenVersion} provided org.apache.maven maven-model ${mavenVersion} provided org.apache.maven maven-core ${mavenVersion} provided org.apache.maven maven-artifact ${mavenVersion} provided org.apache.maven maven-resolver-provider ${mavenVersion} provided org.apache.maven.plugin-tools maven-plugin-annotations 3.15.2 provided javax.inject javax.inject 1 provided org.slf4j slf4j-api ${slf4j.version} provided junit junit test org.hamcrest hamcrest test org.xmlunit xmlunit-legacy 2.11.0 test org.mockito mockito-core 4.11.0 test org.eclipse.sisu org.eclipse.sisu.plexus test org.slf4j slf4j-simple ${slf4j.version} test org.apache.maven.plugin-testing maven-plugin-testing-harness 3.5.1 test org.apache.rat apache-rat-plugin src/it/mrm/repository/services-resource-transformer/*/META-INF/services/org.apache.maven.Shade src/it/mrm/repository/services-resource-transformer-with-reloc-includes-excludes/*/META-INF/services/org.apache.maven.shade rel-path-test-files/** src/it/projects/dep-reduced-pom-use-base-version/repo/org/apache/maven/its/shade/drp/a/0.1-SNAPSHOT/_maven.repositories src/it/projects/mshade-123/sample.txt src/it/projects/MSHADE-133/src/main/resources/myConfig.yml src/it/projects/rerun-with-reloc/src/main/resources/some-ordinary-resource.txt src/it/projects/rerun-without-reloc/src/main/resources/some-ordinary-resource.txt src/it/projects/MSHADE-182/src/main/resources/META-INF/services/relocateme.Service src/it/projects/MSHADE-390-sisu-index/** org.apache.maven.plugins maven-enforcer-plugin enforce-bytecode-version module-info org.vafer:jdependency org.eclipse.sisu sisu-maven-plugin run-its org.apache.maven.plugins maven-jar-plugin test-jar org.apache.maven.plugins maven-invoker-plugin package true src/it/projects src/it/mrm/settings.xml org.apache.maven.plugins:maven-shade-plugin:${project.version}:test-jar org.codehaus.mojo mrm-maven-plugin 1.7.1 src/it/mrm/repository target/mock-repo start stop ================================================ FILE: src/it/MSHADE-321_respectDrpFlag/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.drp test 1.0 jar MSHADE-321 Test that dependency-reduced-pom is created with respect to flag only. Shade plugin starts to create DRP even if the artifact has been renamed because of the configuration shade-it file://${basedir}/repo ignore false org.apache.maven.its.shade.drp a 0.1 org.apache.maven.plugins maven-shade-plugin @project.version@ shade package shade true shade_321 false true target/shade_321.xml ================================================ FILE: src/it/MSHADE-321_respectDrpFlag/repo/org/apache/maven/its/shade/drp/a/0.1/a-0.1.pom ================================================ 4.0.0 org.apache.maven.its.shade.drp a 0.1 jar ================================================ FILE: src/it/MSHADE-321_respectDrpFlag/verify.groovy ================================================ /* * 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 groovy.xml.XmlParser File jarRenamedFile = new File(basedir, "target/shade_321.jar") assert jarRenamedFile.isFile() File pomFile = new File(basedir, "target/shade_321.xml") assert pomFile.isFile() def ns = new groovy.xml.Namespace("http://maven.apache.org/POM/4.0.0") def pom = new XmlParser().parse(pomFile) assert pom[ns.modelVersion].size() == 1 assert pom[ns.dependencies][ns.dependency].size() == 0 ================================================ FILE: src/it/mrm/repository/MSHADE-247/mshade-247-one-0.1-sources.jar/org/apache/maven/its/shade/csj/Test.java ================================================ package org.apache.maven.its.shade.csj; /* * 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 Test { } ================================================ FILE: src/it/mrm/repository/MSHADE-247/mshade-247-one-0.1.pom ================================================ 4.0.0 org.apache.maven.its.shade.csj mshade-247-one 0.1 maven-core-it file:///${basedir}/repo ================================================ FILE: src/it/mrm/repository/MSHADE-247/mshade-247-two-0.1.pom ================================================ 4.0.0 org.apache.maven.its.shade.csj mshade-247-two 0.1 maven-core-it file:///${basedir}/repo ================================================ FILE: src/it/mrm/repository/artifact-includes-excludes/a-0.1.jar/a.properties ================================================ # 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. ================================================ FILE: src/it/mrm/repository/artifact-includes-excludes/a-0.1.pom ================================================ 4.0.0 org.apache.maven.its.shade.aie a 0.1 jar maven-core-it file:///${basedir}/repo ================================================ FILE: src/it/mrm/repository/artifact-includes-excludes/b-0.2.jar/b.properties ================================================ # 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. ================================================ FILE: src/it/mrm/repository/artifact-includes-excludes/b-0.2.pom ================================================ 4.0.0 org.apache.maven.its.shade.aie b 0.2 jar maven-core-it file:///${basedir}/repo ================================================ FILE: src/it/mrm/repository/dep-reduced-pom/a-0.1.pom ================================================ 4.0.0 org.apache.maven.its.shade.drp a 0.1 jar maven-core-it file:///${basedir}/repo ================================================ FILE: src/it/mrm/repository/dep-reduced-pom/b-0.2-client.jar/b-client.properties ================================================ # 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. ================================================ FILE: src/it/mrm/repository/dep-reduced-pom/b-0.2.pom ================================================ 4.0.0 org.apache.maven.its.shade.drp b 0.2 jar maven-core-it file:///${basedir}/repo ================================================ FILE: src/it/mrm/repository/dep-reduced-pom/c-1.pom ================================================ 4.0.0 org.apache.maven.its.shade.drp c 1 pom maven-core-it file:///${basedir}/repo ================================================ FILE: src/it/mrm/repository/dep-reduced-pom-artifactset-provided-excludes/a-0.1.pom ================================================ 4.0.0 org.apache.maven.its.shade.drpape a 0.1 jar UTF-8 maven-core-it file:///${basedir}/repo ================================================ FILE: src/it/mrm/repository/dep-reduced-pom-artifactset-provided-excludes/b-0.1.pom ================================================ 4.0.0 org.apache.maven.its.shade.drpape b 0.1 jar UTF-8 org.apache.maven.its.shade.drpape c 0.1 maven-core-it file:///${basedir}/repo ================================================ FILE: src/it/mrm/repository/dep-reduced-pom-artifactset-provided-excludes/c-0.1.pom ================================================ 4.0.0 org.apache.maven.its.shade.drpape c 0.1 jar UTF-8 maven-core-it file:///${basedir}/repo ================================================ FILE: src/it/mrm/repository/dep-reduced-pom-artifactset-provided-excludes/d-0.1.pom ================================================ 4.0.0 org.apache.maven.its.shade.drpape d 0.1 jar UTF-8 org.apache.maven.its.shade.drpape e 0.1 maven-core-it file:///${basedir}/repo ================================================ FILE: src/it/mrm/repository/dep-reduced-pom-artifactset-provided-excludes/e-0.1.pom ================================================ 4.0.0 org.apache.maven.its.shade.drpape e 0.1 jar UTF-8 maven-core-it file:///${basedir}/repo ================================================ FILE: src/it/mrm/repository/dep-reduced-pom-exclusions/a-0.1.pom ================================================ 4.0.0 org.apache.maven.its.shade.drpe a 0.1 jar maven-core-it file:///${basedir}/repo org.apache.maven.its.shade.drpe b 0.2 org.apache.maven.its.shade.drpe b alt 0.2 ================================================ FILE: src/it/mrm/repository/dep-reduced-pom-exclusions/b-0.2-alt.jar/b-alt.properties ================================================ # 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. ================================================ FILE: src/it/mrm/repository/dep-reduced-pom-exclusions/b-0.2.pom ================================================ 4.0.0 org.apache.maven.its.shade.drpe b 0.2 jar maven-core-it file:///${basedir}/repo org.apache.maven.its.shade.drpe c 1 ================================================ FILE: src/it/mrm/repository/dep-reduced-pom-exclusions/c-1.pom ================================================ 4.0.0 org.apache.maven.its.shade.drpe c 1 jar maven-core-it file:///${basedir}/repo ================================================ FILE: src/it/mrm/repository/dep-reduced-pom-unique/a-0.1.pom ================================================ 4.0.0 org.apache.maven.its.shade.drp a 0.1 jar maven-core-it file:///${basedir}/repo ================================================ FILE: src/it/mrm/repository/dep-reduced-pom-unique/b-0.2.pom ================================================ 4.0.0 org.apache.maven.its.shade.drp b 0.2 jar maven-core-it file:///${basedir}/repo ================================================ FILE: src/it/mrm/repository/dep-reduced-pom-unique/c-1.pom ================================================ 4.0.0 org.apache.maven.its.shade.drp c 1 pom maven-core-it file:///${basedir}/repo ================================================ FILE: src/it/mrm/repository/dep-reduced-pom-use-base-version/a-0.1-20130115.024354-82.pom ================================================ 4.0.0 org.apache.maven.its.shade.drp a 0.1-SNAPSHOT jar maven-core-it file:///${basedir}/repo ================================================ FILE: src/it/mrm/repository/dep-reduced-pom-use-base-version/maven-metadata.xml ================================================ org.apache.maven.its.shade.drp a 0.1-SNAPSHOT true 20130115024354 jar 0.1-20130115.024354-82 20130115024354 pom 0.1-20130115.024354-82 20130115024354 ================================================ FILE: src/it/mrm/repository/filter-artifact-contents/a-0.1.jar/META-INF/maven/org.apache.maven.its.shade.fac/a/pom.properties ================================================ # 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. version=0.1 groupId=org.apache.maven.its.shade.fac artifactId=a ================================================ FILE: src/it/mrm/repository/filter-artifact-contents/a-0.1.jar/a.properties ================================================ # 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. ================================================ FILE: src/it/mrm/repository/filter-artifact-contents/a-0.1.jar/org/a.properties ================================================ # 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. ================================================ FILE: src/it/mrm/repository/filter-artifact-contents/a-0.1.jar/org/apache/a.properties ================================================ # 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. ================================================ FILE: src/it/mrm/repository/filter-artifact-contents/a-0.1.jar/org/apache/maven/a.properties ================================================ # 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. ================================================ FILE: src/it/mrm/repository/filter-artifact-contents/a-0.1.pom ================================================ 4.0.0 org.apache.maven.its.shade.fac a 0.1 jar maven-core-it file:///${basedir}/repo ================================================ FILE: src/it/mrm/repository/filter-artifact-contents/b-0.1-client.jar/META-INF/maven/org.apache.maven.its.shade.fac/b/pom.properties ================================================ # 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. version=0.1 groupId=org.apache.maven.its.shade.fac artifactId=b ================================================ FILE: src/it/mrm/repository/filter-artifact-contents/b-0.1-client.jar/b.properties ================================================ # 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. ================================================ FILE: src/it/mrm/repository/filter-artifact-contents/b-0.1-client.jar/org/apache/b.properties ================================================ # 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. ================================================ FILE: src/it/mrm/repository/filter-artifact-contents/b-0.1-client.jar/org/apache/maven/b/b.properties ================================================ # 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. ================================================ FILE: src/it/mrm/repository/filter-artifact-contents/b-0.1-client.jar/org/apache/maven/b.properties ================================================ # 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. ================================================ FILE: src/it/mrm/repository/filter-artifact-contents/b-0.1-client.jar/org/b.properties ================================================ # 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. ================================================ FILE: src/it/mrm/repository/filter-artifact-contents/b-0.1.pom ================================================ 4.0.0 org.apache.maven.its.shade.fac b 0.1 jar maven-core-it file:///${basedir}/repo ================================================ FILE: src/it/mrm/repository/non-runtime-scope-excluded/compile-1.0.jar/compile.properties ================================================ # 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. ================================================ FILE: src/it/mrm/repository/non-runtime-scope-excluded/compile-1.0.pom ================================================ 4.0.0 org.apache.maven.its.shade.nrse compile 1.0 jar MSHADE Test that dependencies not matching runtime scope are automatically excluded. maven-core-it file:///${basedir}/repo ================================================ FILE: src/it/mrm/repository/non-runtime-scope-excluded/provided-1.0.jar/provided.properties ================================================ # 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. ================================================ FILE: src/it/mrm/repository/non-runtime-scope-excluded/provided-1.0.pom ================================================ 4.0.0 org.apache.maven.its.shade.nrse provided 1.0 jar MSHADE Test that dependencies not matching runtime scope are automatically excluded. maven-core-it file:///${basedir}/repo ================================================ FILE: src/it/mrm/repository/non-runtime-scope-excluded/runtime-1.0.jar/runtime.properties ================================================ # 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. ================================================ FILE: src/it/mrm/repository/non-runtime-scope-excluded/runtime-1.0.pom ================================================ 4.0.0 org.apache.maven.its.shade.nrse runtime 1.0 jar MSHADE Test that dependencies not matching runtime scope are automatically excluded. maven-core-it file:///${basedir}/repo ================================================ FILE: src/it/mrm/repository/non-runtime-scope-excluded/test-1.0.jar/test.properties ================================================ # 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. ================================================ FILE: src/it/mrm/repository/non-runtime-scope-excluded/test-1.0.pom ================================================ 4.0.0 org.apache.maven.its.shade.nrse test 1.0 jar MSHADE Test that dependencies not matching runtime scope are automatically excluded. maven-core-it file:///${basedir}/repo ================================================ FILE: src/it/mrm/repository/plugin-descriptor-relocation/comp-0.1.pom ================================================ 4.0.0 org.apache.maven.its.shade.cdr comp 0.1 jar maven-core-it file:///${basedir}/repo . pom.xml src/** src/main/resources ================================================ FILE: src/it/mrm/repository/services-resource-transformer/one-0.1.jar/META-INF/services/org.apache.maven.Shade ================================================ one # NOTE: No newline terminates this line/file ================================================ FILE: src/it/mrm/repository/services-resource-transformer/one-0.1.pom ================================================ 4.0.0 org.apache.maven.its.shade.srt one 0.1 jar maven-core-it file:///${basedir}/repo ================================================ FILE: src/it/mrm/repository/services-resource-transformer/two-0.1.jar/META-INF/services/org.apache.maven.Shade ================================================ two # NOTE: No newline terminates this line/file ================================================ FILE: src/it/mrm/repository/services-resource-transformer/two-0.1.pom ================================================ 4.0.0 org.apache.maven.its.shade.srt two 0.1 jar maven-core-it file:///${basedir}/repo ================================================ FILE: src/it/mrm/repository/services-resource-transformer-with-reloc-includes-excludes/mshade-237-one-0.1.jar/META-INF/services/org.apache.maven.shade ================================================ org.apache.maven.its.shade.One ================================================ FILE: src/it/mrm/repository/services-resource-transformer-with-reloc-includes-excludes/mshade-237-one-0.1.pom ================================================ 4.0.0 org.apache.maven.its.shade.srt mshade-237-one 0.1 jar maven-core-it file:///${basedir}/repo ================================================ FILE: src/it/mrm/repository/services-resource-transformer-with-reloc-includes-excludes/mshade-237-two-0.1.jar/META-INF/services/org.apache.maven.shade ================================================ org.apache.maven.its.shade.Two ================================================ FILE: src/it/mrm/repository/services-resource-transformer-with-reloc-includes-excludes/mshade-237-two-0.1.pom ================================================ 4.0.0 org.apache.maven.its.shade.srt mshade-237-two 0.1 jar maven-core-it file:///${basedir}/repo ================================================ FILE: src/it/mrm/settings.xml ================================================ mrm-maven-plugin Mock Repository Manager @mrm.repository.url@ * it-repo snapshots @mrm.repository.url@ true ignore never true ignore always snapshots @mrm.repository.url@ true ignore never true ignore always it-repo ================================================ FILE: src/it/projects/MSHADE-105/bundle/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.mr MSHADE-105-ROOT 1.0-SNAPSHOT MSHADE-105-BUNDLE bundle ${project.groupId} MSHADE-105-SHADED-JAR ${project.version} org.apache.felix maven-bundle-plugin 5.1.9 true * ================================================ FILE: src/it/projects/MSHADE-105/bundle/src/main/java/test/Dummy.java ================================================ package test; /* * 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 internal.io.IOUtils; import java.io.IOException; import java.io.InputStream; public class Dummy { public static void dump(InputStream in) throws IOException { IOUtils.copy(in, System.out); } } ================================================ FILE: src/it/projects/MSHADE-105/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.mr MSHADE-105-ROOT 1.0-SNAPSHOT pom shaded-jar bundle ================================================ FILE: src/it/projects/MSHADE-105/shaded-jar/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.mr MSHADE-105-ROOT 1.0-SNAPSHOT MSHADE-105-SHADED-JAR commons-io commons-io 2.14.0 org.apache.maven.plugins maven-shade-plugin @project.version@ package shade org.apache.commons.io internal.io ================================================ FILE: src/it/projects/MSHADE-105/verify.bsh ================================================ /* * 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.io.*; import java.util.jar.*; import java.util.*; JarFile jarFile = new JarFile( new File( basedir, "bundle/target/MSHADE-105-BUNDLE-1.0-SNAPSHOT.jar" ) ); Manifest mf = jarFile.getManifest(); jarFile.close(); String importPackage = mf.getMainAttributes().getValue( "Import-Package" ); System.out.println("importPackage:"+importPackage); if ( importPackage.indexOf("org.apache.commons.io" ) >=0 ) { throw new IllegalStateException( "MANIFEST.MF has Import-Package entry with org.apache.commons.io" ); } return true; ================================================ FILE: src/it/projects/MSHADE-114/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade MSHADE-114 1.0-SNAPSHOT org.apache.maven.plugins maven-shade-plugin @project.version@ shade package shade .so org.jacoco.agent.${rt}.JacocoAgent ================================================ FILE: src/it/projects/MSHADE-133/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade MSHADE-133 1.0-SNAPSHOT org.apache.maven.plugins maven-shade-plugin @project.version@ shade package shade myConfig.yml logback.xml ================================================ FILE: src/it/projects/MSHADE-133/src/main/resources/logback.xml ================================================ ================================================ FILE: src/it/projects/MSHADE-133/src/main/resources/myConfig.yml ================================================ ================================================ FILE: src/it/projects/MSHADE-133/verify.groovy ================================================ /* * 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/MSHADE-133-1.0-SNAPSHOT.jar" ) ) assert jarFile.getJarEntry("myComfig.yml") == null assert jarFile.getJarEntry("logback.xml") == null ================================================ FILE: src/it/projects/MSHADE-155/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.fnb shadedartifactid 1.0 MSHADE-155 :: using shadedArtifactId Test that the shaded artifact has the correct artifactId which is defined by shadedArtifactId. org.apache.maven.plugins maven-shade-plugin @project.version@ create-shaded-artifact package shade true ${project.artifactId}-special false ================================================ FILE: src/it/projects/MSHADE-155/src/main/resources/META-INF/ejb-jar.xml ================================================ ================================================ FILE: src/it/projects/MSHADE-155/verify.groovy ================================================ /* * 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. */ File targetFolder = new File ( basedir, "target" ) File originalArtifact = new File ( targetFolder, "shadedartifactid-1.0.jar" ) assert originalArtifact.isFile() File shadedArtifact = new File ( targetFolder, "shadedartifactid-special-1.0-shaded.jar") assert shadedArtifact.isFile() ================================================ FILE: src/it/projects/MSHADE-182/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade MSHADE-182 1.0-SNAPSHOT org.apache.maven.plugins maven-shade-plugin @project.version@ shade package shade relocateme relocated ================================================ FILE: src/it/projects/MSHADE-182/src/main/resources/META-INF/services/relocateme.Service ================================================ relocateme.ServiceImpl ================================================ FILE: src/it/projects/MSHADE-182/verify.groovy ================================================ /* * 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/MSHADE-182-1.0-SNAPSHOT.jar")) def jarEntry = jarFile.getJarEntry("META-INF/services/relocated.Service") def content = new java.io.BufferedReader(new java.io.InputStreamReader(jarFile.getInputStream(jarEntry))) assert content.readLine() == "relocated.ServiceImpl" ================================================ FILE: src/it/projects/MSHADE-183/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.mt test 1.0 jar MSHADE-183 Test that reproduces the issue described in MSHADE-183. org.apache.maven.plugins maven-shade-plugin @project.version@ org.apache.maven.plugins maven-compiler-plugin @version.maven-compiler-plugin@ org.apache.maven.plugins maven-install-plugin @version.maven-install-plugin@ org.apache.maven.plugins maven-jar-plugin @version.maven-jar-plugin@ org.apache.maven.Main FAILED PASSED org.apache.maven.plugins maven-resources-plugin @version.maven-resources-plugin@ org.apache.maven.plugins maven-shade-plugin @project.version@ attach-shade package shade false org.apache.maven.Shade PASSED org.apache.maven.plugins maven-surefire-plugin @version.maven-surefire@ ================================================ FILE: src/it/projects/MSHADE-183/verify.bsh ================================================ /* * 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.io.*; import java.util.jar.*; // NOTE: We deliberately use JarInputStream and not JarFile here! JarInputStream jarStream = new JarInputStream( new FileInputStream( new File( basedir, "target/test-1.0.jar" ) ) ); Manifest mf = jarStream.getManifest(); jarStream.close(); if ( mf == null ) { throw new IllegalStateException( "META-INF/MANIFEST.MF is missing" ); } if ( !"PASSED".equals( mf.getMainAttributes().getValue( "Test-Entry" ) ) ) { throw new IllegalStateException( "META-INF/MANIFEST.MF is incomplete" ); } if ( !"PASSED".equals( mf.getMainAttributes().getValue( "Original-Entry" ) ) ) { throw new IllegalStateException( "META-INF/MANIFEST.MF is incomplete" ); } if ( !"org.apache.maven.Shade".equals( mf.getMainAttributes().getValue( "Main-Class" ) ) ) { throw new IllegalStateException( "META-INF/MANIFEST.MF is incomplete" ); } if ( null != mf.getMainAttributes().getValue( "Implementation-Build" ) ) { throw new IllegalStateException( "META-INF/MANIFEST.MF Implementation-Build content is not null as expected. (" + mf.getMainAttributes().entrySet() + ")" ); } ================================================ FILE: src/it/projects/MSHADE-185/invoker.properties ================================================ # 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 = 9- ================================================ FILE: src/it/projects/MSHADE-185/pom.xml ================================================ 4.0.0 test.shade system-dep jar 1.0.0-SNAPSHOT jline jline 2.12 com.sun tools 1.6 system ${java.home}/../lib/tools.jar true @project.groupId@ @project.artifactId@ @project.version@ package shade false true true jline:jline jline org.crsh.console.jline ================================================ FILE: src/it/projects/MSHADE-185/verify.groovy ================================================ /* * 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 groovy.xml.XmlSlurper; File pomFile = new File( basedir, "dependency-reduced-pom.xml" ); assert pomFile.isFile() def project = new XmlSlurper().parse( pomFile ) assert project.dependencies.dependency[0].artifactId == 'tools' assert project.dependencies.dependency[0].groupId == 'com.sun' assert project.dependencies.dependency[0].version == '1.6' assert project.dependencies.dependency[0].scope == 'system' // Check that the dependency-reduced pom does not have expand properties in // dependencies. They should be left untouched. assert project.dependencies.dependency[0].systemPath == '${java.home}/../lib/tools.jar' ================================================ FILE: src/it/projects/MSHADE-232_ResourceBundleAppendingTransformer/invoker.properties ================================================ # 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.goals=clean package ================================================ FILE: src/it/projects/MSHADE-232_ResourceBundleAppendingTransformer/one/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.pp mshade-232 1.0-SNAPSHOT one ================================================ FILE: src/it/projects/MSHADE-232_ResourceBundleAppendingTransformer/one/src/main/resources/org/apache/maven/plugins/shade/its/Message.properties ================================================ # 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. one = one ================================================ FILE: src/it/projects/MSHADE-232_ResourceBundleAppendingTransformer/one/src/main/resources/org/apache/maven/plugins/shade/its/Message_nl.properties ================================================ # 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. one = een ================================================ FILE: src/it/projects/MSHADE-232_ResourceBundleAppendingTransformer/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.pp mshade-232 1.0-SNAPSHOT pom UTF-8 org.apache.maven.its.shade.pp one ${project.version} one two ================================================ FILE: src/it/projects/MSHADE-232_ResourceBundleAppendingTransformer/two/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.pp mshade-232 1.0-SNAPSHOT two org.apache.maven.its.shade.pp one org.apache.maven.plugins maven-shade-plugin @project.version@ attach-shade package shade false org/apache/maven/plugins/shade/its/Message ================================================ FILE: src/it/projects/MSHADE-232_ResourceBundleAppendingTransformer/two/src/main/resources/org/apache/maven/plugins/shade/its/Message.properties ================================================ # 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. two = two ================================================ FILE: src/it/projects/MSHADE-232_ResourceBundleAppendingTransformer/two/src/main/resources/org/apache/maven/plugins/shade/its/Message_nl.properties ================================================ # 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. two = twee ================================================ FILE: src/it/projects/MSHADE-232_ResourceBundleAppendingTransformer/verify.groovy ================================================ /* * 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, "two/target/two-1.0-SNAPSHOT.jar")) def jarEntry = jarFile.getJarEntry("org/apache/maven/plugins/shade/its/Message.properties") def props = new Properties(); props.load(jarFile.getInputStream(jarEntry)); assert props.one == 'one' assert props.two == 'two' jarEntry = jarFile.getJarEntry("org/apache/maven/plugins/shade/its/Message_nl.properties") props = new Properties(); props.load(jarFile.getInputStream(jarEntry)); assert props.one == 'een' assert props.two == 'twee' ================================================ FILE: src/it/projects/MSHADE-239_finalName-attachments/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.fns artifactId version https://issues.apache.org/jira/browse/MSHADE-239 crapola org.apache.maven.plugins maven-shade-plugin @project.version@ shade ${project.artifactId}-${project.version}-${some-other-crap}-exe true true true exe true ================================================ FILE: src/it/projects/MSHADE-239_finalName-attachments/verify.groovy ================================================ /* * 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. */ assert new File( basedir, 'target/artifactId-version-crapola-exe.jar' ).exists() : "target/artifactId-version-crapola-exe.jar doesn't exist" assert new File( basedir, 'target/artifactId-version-crapola-exe-sources.jar' ).exists() : "target/artifactId-version-crapola-exe-sources.jar doesn't exist" assert new File( basedir, 'target/artifactId-version-crapola-exe-tests.jar' ).exists() : "target/artifactId-version-crapola-exe-tests.jar doesn't exist" ================================================ FILE: src/it/projects/MSHADE-240_reloc-mavenfiles/pom.xml ================================================ 4.0.0 org.apache.maven.plugins.shade.its mshade240 1.0-SNAPSHOT https://issues.apache.org/jira/browse/MSHADE-240 org.apache.maven maven-core 3.0 org.apache.maven.plugins maven-shade-plugin @project.version@ shade false META-INF/maven META-INF/shade/maven META-INF/maven/${project.groupId}/${project.artifactId}/pom.* ================================================ FILE: src/it/projects/MSHADE-240_reloc-mavenfiles/verify.groovy ================================================ /* * 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/mshade240-1.0-SNAPSHOT.jar" ) ) try { assert null != jarFile.getJarEntry( "META-INF/maven/org.apache.maven.plugins.shade.its/mshade240/pom.properties" ) assert null != jarFile.getJarEntry( "META-INF/maven/org.apache.maven.plugins.shade.its/mshade240/pom.xml" ) assert null != jarFile.getJarEntry( "META-INF/shade/maven/org.apache.maven/maven-core/pom.properties" ) assert null != jarFile.getJarEntry( "META-INF/shade/maven/org.apache.maven/maven-core/pom.xml" ) assert null == jarFile.getJarEntry( "META-INF/shade/maven/org.apache.maven.plugins.shade.its/mshade240/pom.properties" ) assert null == jarFile.getJarEntry( "META-INF/shade/maven/org.apache.maven.plugins.shade.its/mshade240/pom.xml" ) assert null == jarFile.getJarEntry( "META-INF/maven/org.apache.maven/maven-core/pom.properties" ) assert null == jarFile.getJarEntry( "META-INF/maven/org.apache.maven/maven-core/pom.xml" ) } finally { jarFile.close() } ================================================ FILE: src/it/projects/MSHADE-247/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.csj mshade-247 1.0 https://issues.apache.org/jira/browse/MSHADE-247 Test that setting createSourcesJar to true does not fail the build when no sources Jar is available. org.apache.maven.its.shade.csj mshade-247-one 0.1 org.apache.maven.its.shade.csj mshade-247-two 0.1 org.apache.maven.plugins maven-shade-plugin @project.version@ shade package shade true ================================================ FILE: src/it/projects/MSHADE-258_module_relocation/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.csj mshade-258 1.0-SNAPSHOT https://issues.apache.org/jira/browse/MSHADE-258 RemappingClassAdapter is deprecated and throws an exception with ASM 6.0 beta org.ow2.asm asm @asmVersion@ org.apache.maven.plugins maven-shade-plugin @project.version@ shade shade org.objectweb.asm org.shaded.objectweb.asm ================================================ FILE: src/it/projects/MSHADE-258_module_relocation/verify.groovy ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ def buildLog = new File ( basedir , "build.log" ) assert buildLog.text.contains( "[WARNING] Discovered module-info.class. Shading will break its strong encapsulation." ) def jarFile = new java.util.jar.JarFile( new File( basedir, "target/mshade-258-1.0-SNAPSHOT.jar" ) ) try { assert null == jarFile.getJarEntry( "module-info.class" ) } finally { jarFile.close() } ================================================ FILE: src/it/projects/MSHADE-260-reloc-serialized-lambda/README.txt ================================================ # Serialized Lambda Relocation Test This integration test verifies that the maven-shade-plugin correctly rewrites serialized lambda metadata when relocating classes. ## Background When a lambda expression or method reference uses a `Serializable` functional interface, the Java compiler generates a `SerializedLambda` object that contains metadata about the lambda's implementation class. This metadata includes the class name, which must be rewritten during shading to reflect the relocated package structure. ## Test Structure - **MapFunction.java** - A `Serializable` functional interface - **Main.java** - Uses a method reference (`processor::process`) that creates a serialized lambda - **Processor.java** - Contains the method used as a method reference - **DataHolder.java** - Simple data class passed through the lambda ## Configuration The test uses the `true` option: ```xml org.apache.maven.its.shade.reloc.lambda org.apache.maven.its.shade.reloc.shaded.lambda true ``` ## What the Test Verifies 1. All classes are relocated from `org.apache.maven.its.shade.reloc.lambda` to `org.apache.maven.its.shade.reloc.shaded.lambda` 2. The original package paths do NOT exist in the shaded JAR 3. Most importantly: The serialized lambda metadata (in the bytecode's constant pool) references the shaded package, not the original ## Running the Test ```bash cd /path/to/maven-shade-plugin mvn verify -Prun-its -Dinvoker.test=reloc-serialized-lambda ``` ## Expected Behavior After shading: - `Main.class` should be at `org/apache/maven/its/shade/reloc/shaded/lambda/Main.class` - The bytecode should NOT contain references to the original package path `org/apache/maven/its/shade/reloc/lambda/Processor` - All lambda metadata should use the shaded path `org/apache/maven/its/shade/reloc/shaded/lambda/Processor` ================================================ FILE: src/it/projects/MSHADE-260-reloc-serialized-lambda/invoker.properties ================================================ # 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. # Lambdas were introduced in Java 8 invoker.java.version = 1.8+ # Run package goal to trigger shade invoker.goals = clean package ================================================ FILE: src/it/projects/MSHADE-260-reloc-serialized-lambda/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.reloc serialized-lambda 1.0 jar Serialized Lambda Relocation Test Test that serialized lambda metadata is properly relocated when shading. This test uses a Serializable functional interface with a method reference to ensure the lambda's captured class information is rewritten. org.apache.maven.plugins maven-shade-plugin @project.version@ shade package shade org.apache.maven.its.shade.reloc.lambda org.apache.maven.its.shade.reloc.shaded.lambda true ================================================ FILE: src/it/projects/MSHADE-260-reloc-serialized-lambda/src/main/java/org/apache/maven/its/shade/reloc/lambda/DataHolder.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.its.shade.reloc.lambda; /** * A simple data class (record) used to demonstrate serialized lambda relocation. */ public class DataHolder { private final String value; public DataHolder(String value) { this.value = value; } public String getValue() { return value; } } ================================================ FILE: src/it/projects/MSHADE-260-reloc-serialized-lambda/src/main/java/org/apache/maven/its/shade/reloc/lambda/Main.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.its.shade.reloc.lambda; /** * Main class that uses a method reference with a Serializable functional interface. * When compiled, this creates a serialized lambda that captures class metadata. */ public class Main { public static void main(String[] args) { Processor processor = new Processor(); DataHolder data = new DataHolder("test"); // This method reference creates a serialized lambda String result = transform(data, processor::process); System.out.println(result); } public static String transform(DataHolder value, MapFunction mapper) { return mapper.map(value); } } ================================================ FILE: src/it/projects/MSHADE-260-reloc-serialized-lambda/src/main/java/org/apache/maven/its/shade/reloc/lambda/MapFunction.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.its.shade.reloc.lambda; import java.io.Serializable; /** * A serializable functional interface that will cause lambdas/method references * to have their class information stored in the serialized lambda metadata. */ @FunctionalInterface public interface MapFunction extends Serializable { R map(T t); } ================================================ FILE: src/it/projects/MSHADE-260-reloc-serialized-lambda/src/main/java/org/apache/maven/its/shade/reloc/lambda/Processor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.its.shade.reloc.lambda; /** * Processor class that contains a method used as a method reference. */ public class Processor { public String process(DataHolder data) { return "Processed: " + data.getValue(); } } ================================================ FILE: src/it/projects/MSHADE-260-reloc-serialized-lambda/verify.groovy ================================================ /* * 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.jar.* // Path to the shaded JAR File jarFile = new File(basedir, "target/serialized-lambda-1.0.jar") assert jarFile.exists() : "Shaded JAR not found: ${jarFile}" JarFile jar = new JarFile(jarFile) // Check 1: Verify shaded classes exist (with relocated package) def shadedClasses = [ "org/apache/maven/its/shade/reloc/shaded/lambda/Main.class", "org/apache/maven/its/shade/reloc/shaded/lambda/Processor.class", "org/apache/maven/its/shade/reloc/shaded/lambda/DataHolder.class", "org/apache/maven/its/shade/reloc/shaded/lambda/MapFunction.class" ] shadedClasses.each { path -> assert jar.getEntry(path) != null : "Expected shaded class not found: ${path}" } // Check 2: Verify original classes do NOT exist (they should be relocated) def originalClasses = [ "org/apache/maven/its/shade/reloc/lambda/Main.class", "org/apache/maven/its/shade/reloc/lambda/Processor.class", "org/apache/maven/its/shade/reloc/lambda/DataHolder.class", "org/apache/maven/its/shade/reloc/lambda/MapFunction.class" ] originalClasses.each { path -> assert jar.getEntry(path) == null : "Original class should have been relocated: ${path}" } // Check 3: Read the Main class bytes and verify serialized lambda metadata is relocated def mainEntry = jar.getJarEntry("org/apache/maven/its/shade/reloc/shaded/lambda/Main.class") if (mainEntry != null) { def is = jar.getInputStream(mainEntry) def baos = new ByteArrayOutputStream() def buffer = new byte[1024] int len while ((len = is.read(buffer)) != -1) { baos.write(buffer, 0, len) } is.close() // Convert class bytes to string for pattern searching // The serialized lambda metadata should contain the SHADED package, not original def classContent = new String(baos.toByteArray(), "ISO-8859-1") // Look for the SerializedLambda bootstrap method marker // This appears in the bytecode when lambdas are used if (classContent.contains("SerializedLambda")) { // If we have SerializedLambda, verify the implementation class reference // The implementation class should point to the shaded package // Check that the original package name does NOT appear in serialized metadata assert !classContent.contains("org/apache/maven/its/shade/reloc/lambda/Processor") : "Serialized lambda metadata still contains original package path. " + "The class reference should have been relocated to shaded package." assert !classContent.contains("org/apache/maven/its/shade/reloc/lambda") : "Serialized lambda metadata still contains original package path. " + "The class reference should have been relocated to shaded package." } } // Check 4: Search all class files for any lingering original package references def entries = jar.entries() boolean foundSerializedLambdaMetadata = false while (entries.hasMoreElements()) { def entry = entries.nextElement() if (entry.getName().endsWith(".class")) { def is = jar.getInputStream(entry) def baos = new ByteArrayOutputStream() def buffer = new byte[1024] int len while ((len = is.read(buffer)) != -1) { baos.write(buffer, 0, len) } is.close() def classContent = new String(baos.toByteArray(), "ISO-8859-1") // Check for SerializedLambda constant pool entries if (classContent.contains("java/lang/invoke/LambdaMetafactory") || classContent.contains("SerializedLambda")) { foundSerializedLambdaMetadata = true // If this class uses lambdas, verify it uses the shaded package // The original package should not appear in constant pool references assert !(classContent.contains("org/apache/maven/its/shade/reloc/lambda/" + "Processor") || classContent.contains("org/apache/maven/its/shade/reloc/lambda/" + "Main") || classContent.contains("org/apache/maven/its/shade/reloc/lambda/" + "DataHolder")) : "Class ${entry.getName()} contains reference to original " + "package in lambda metadata. All references should use shaded " + "package: org/apache/maven/its/shade/reloc/shaded/lambda/" } } } if (!foundSerializedLambdaMetadata) { println "Warning: No serialized lambda metadata found in classes. " + "This may indicate the test classes were not compiled with lambda usage." } jar.close() println "Serialized lambda relocation test PASSED!" println "All classes properly relocated and no original package references found." ================================================ FILE: src/it/projects/MSHADE-284_shadeTestJar/api/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.stj mshade-284-parent 1.0 mshade-284-api ================================================ FILE: src/it/projects/MSHADE-284_shadeTestJar/api/src/main/java/Api.java ================================================ /* * 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 Api { } ================================================ FILE: src/it/projects/MSHADE-284_shadeTestJar/api/src/main/resources/api-resource.txt ================================================ # 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. ================================================ FILE: src/it/projects/MSHADE-284_shadeTestJar/api/src/test/java/ApiTest.java ================================================ /* * 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 ApiTest { public static void main(String[] args) { new Api(); } } ================================================ FILE: src/it/projects/MSHADE-284_shadeTestJar/api/src/test/resources/api-test-resource.txt ================================================ # 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. ================================================ FILE: src/it/projects/MSHADE-284_shadeTestJar/impl/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.stj mshade-284-parent 1.0 mshade-284-impl org.apache.maven.its.shade.stj mshade-284-api org.apache.maven.its.shade.stj mshade-284-api test-jar ================================================ FILE: src/it/projects/MSHADE-284_shadeTestJar/impl/src/main/java/Impl.java ================================================ /* * 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 Impl extends Api { } ================================================ FILE: src/it/projects/MSHADE-284_shadeTestJar/impl/src/main/resources/impl-resource.txt ================================================ # 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. ================================================ FILE: src/it/projects/MSHADE-284_shadeTestJar/impl/src/test/java/ImplTest.java ================================================ /* * 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 ImplTest extends ApiTest { public static void main(String[] args) { new Impl(); } } ================================================ FILE: src/it/projects/MSHADE-284_shadeTestJar/impl/src/test/resources/impl-test-resource.txt ================================================ # 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. ================================================ FILE: src/it/projects/MSHADE-284_shadeTestJar/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.stj mshade-284-parent pom 1.0 api impl uber org.apache.maven.its.shade.stj mshade-284-api 1.0 org.apache.maven.its.shade.stj mshade-284-api 1.0 test-jar test org.apache.maven.its.shade.stj mshade-284-impl 1.0 org.apache.maven.its.shade.stj mshade-284-impl 1.0 test-jar test maven-jar-plugin test-jar ================================================ FILE: src/it/projects/MSHADE-284_shadeTestJar/uber/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.stj mshade-284-parent 1.0 mshade-284-uber org.apache.maven.its.shade.stj mshade-284-api org.apache.maven.its.shade.stj mshade-284-api test-jar org.apache.maven.its.shade.stj mshade-284-impl org.apache.maven.its.shade.stj mshade-284-impl test-jar maven-shade-plugin @project.version@ shade true ================================================ FILE: src/it/projects/MSHADE-284_shadeTestJar/verify.groovy ================================================ /* * 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, "uber/target/mshade-284-uber-1.0.jar" ) ) try { assert null != jarFile.getJarEntry( "Api.class" ) assert null != jarFile.getJarEntry( "api-resource.txt" ) assert null != jarFile.getJarEntry( "Impl.class" ) assert null != jarFile.getJarEntry( "impl-resource.txt" ) assert null == jarFile.getJarEntry( "ApiTest.class" ) assert null == jarFile.getJarEntry( "api-test-resource.txt" ) assert null == jarFile.getJarEntry( "ImplTest.class" ) assert null == jarFile.getJarEntry( "impl-test-resource.txt" ) } finally { jarFile.close() } def testJarFile = new java.util.jar.JarFile( new File( basedir, "uber/target/mshade-284-uber-1.0-tests.jar" ) ) try { assert null == testJarFile.getJarEntry( "Api.class" ) assert null == testJarFile.getJarEntry( "api-resource.txt" ) assert null == testJarFile.getJarEntry( "Impl.class" ) assert null == testJarFile.getJarEntry( "impl-resource.txt" ) assert null != testJarFile.getJarEntry( "ApiTest.class" ) assert null != testJarFile.getJarEntry( "api-test-resource.txt" ) assert null != testJarFile.getJarEntry( "ImplTest.class" ) assert null != testJarFile.getJarEntry( "impl-test-resource.txt" ) } finally { testJarFile.close() } ================================================ FILE: src/it/projects/MSHADE-285_createTestSourcesJar/api/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.stj mshade-285-parent 1.0 mshade-285-api ================================================ FILE: src/it/projects/MSHADE-285_createTestSourcesJar/api/src/main/java/Api.java ================================================ /* * 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. */ /** * Production API class. */ public class Api { } ================================================ FILE: src/it/projects/MSHADE-285_createTestSourcesJar/api/src/test/java/ApiTest.java ================================================ /* * 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. */ /** * Test API class. */ public class ApiTest { public static void main(String[] args) { new Api(); } } ================================================ FILE: src/it/projects/MSHADE-285_createTestSourcesJar/impl/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.stj mshade-285-parent 1.0 mshade-285-impl org.apache.maven.its.shade.stj mshade-285-api org.apache.maven.its.shade.stj mshade-285-api test-jar ================================================ FILE: src/it/projects/MSHADE-285_createTestSourcesJar/impl/src/main/java/Impl.java ================================================ /* * 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. */ /** * Production implementation class. */ public class Impl extends Api { } ================================================ FILE: src/it/projects/MSHADE-285_createTestSourcesJar/impl/src/test/java/ImplTest.java ================================================ /* * 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. */ /** * Test implementation class. */ public class ImplTest extends ApiTest { public static void main(String[] args) { new Impl(); } } ================================================ FILE: src/it/projects/MSHADE-285_createTestSourcesJar/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.stj mshade-285-parent pom 1.0 api impl uber org.apache.maven.its.shade.stj mshade-285-api 1.0 org.apache.maven.its.shade.stj mshade-285-api 1.0 test-jar test org.apache.maven.its.shade.stj mshade-285-impl 1.0 org.apache.maven.its.shade.stj mshade-285-impl 1.0 test-jar test maven-source-plugin test-jar maven-jar-plugin test-jar ================================================ FILE: src/it/projects/MSHADE-285_createTestSourcesJar/uber/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.stj mshade-285-parent 1.0 mshade-285-uber org.apache.maven.its.shade.stj mshade-285-api org.apache.maven.its.shade.stj mshade-285-api test-jar org.apache.maven.its.shade.stj mshade-285-impl org.apache.maven.its.shade.stj mshade-285-impl test-jar maven-shade-plugin @project.version@ shade true ================================================ FILE: src/it/projects/MSHADE-285_createTestSourcesJar/verify.groovy ================================================ /* * 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 testSourceJarFile = new java.util.jar.JarFile( new File( basedir, "uber/target/mshade-285-uber-1.0-test-sources.jar" ) ) try { assert null == testSourceJarFile.getJarEntry( "Api.java" ) assert null == testSourceJarFile.getJarEntry( "Impl.java" ) assert null != testSourceJarFile.getJarEntry( "ApiTest.java" ) assert null != testSourceJarFile.getJarEntry( "ImplTest.java" ) } finally { testSourceJarFile.close() } ================================================ FILE: src/it/projects/MSHADE-313_minimized-services/dependency-service/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.mj dependency-service 1.0 ================================================ FILE: src/it/projects/MSHADE-313_minimized-services/dependency-service/src/main/java/DependencyReferencedClass.java ================================================ /* * 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 DependencyReferencedClass { } ================================================ FILE: src/it/projects/MSHADE-313_minimized-services/dependency-service/src/main/java/DependencyServiceClass.java ================================================ /* * 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 DependencyServiceClass implements DependencyServiceInterface { private static DependencyReferencedClass anEssentialDependency; } ================================================ FILE: src/it/projects/MSHADE-313_minimized-services/dependency-service/src/main/java/DependencyServiceInterface.java ================================================ /* * 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 interface DependencyServiceInterface { } ================================================ FILE: src/it/projects/MSHADE-313_minimized-services/dependency-service/src/main/java/DependencyUnreferencedClass.java ================================================ /* * 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 DependencyUnreferencedClass { } ================================================ FILE: src/it/projects/MSHADE-313_minimized-services/dependency-service/src/main/resources/META-INF/services/DependencyServiceInterface ================================================ # # 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. # DependencyServiceClass # Please do not remove comments or whitespace; they are part of the IT test. ================================================ FILE: src/it/projects/MSHADE-313_minimized-services/invoker.properties ================================================ # 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. # jdependency-2.6.0 needs Java 8+ invoker.java.version = 1.8+ ================================================ FILE: src/it/projects/MSHADE-313_minimized-services/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.mj aggregate 1.0 pom MSHADE-313 Prevent minimizeJar from excluding classes that are used by services. unused-service used-service dependency-service test ================================================ FILE: src/it/projects/MSHADE-313_minimized-services/test/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.mj test 1.0 org.apache.maven.its.shade.mj unused-service 1.0 org.apache.maven.its.shade.mj used-service 1.0 org.apache.maven.plugins maven-compiler-plugin @version.maven-compiler-plugin@ org.apache.maven.plugins maven-shade-plugin @project.version@ attach-shade package shade false true ================================================ FILE: src/it/projects/MSHADE-313_minimized-services/test/src/main/java/Main.java ================================================ /* * 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.ServiceLoader; public class Main { public static void main( String[] args ) { ServiceLoader.load( SomeServiceInterface.class ); } } ================================================ FILE: src/it/projects/MSHADE-313_minimized-services/unused-service/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.mj unused-service 1.0 ================================================ FILE: src/it/projects/MSHADE-313_minimized-services/unused-service/src/main/java/UnusedServiceClass.java ================================================ /* * 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 UnusedServiceClass implements UnusedServiceInterface { } ================================================ FILE: src/it/projects/MSHADE-313_minimized-services/unused-service/src/main/java/UnusedServiceInterface.java ================================================ /* * 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 interface UnusedServiceInterface { } ================================================ FILE: src/it/projects/MSHADE-313_minimized-services/unused-service/src/main/resources/META-INF/services/UnusedServiceInterface ================================================ # # 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. # UnusedServiceClass # Please do not remove comments or whitespace; they are part of the IT test. ================================================ FILE: src/it/projects/MSHADE-313_minimized-services/used-service/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.mj used-service 1.0 org.apache.maven.its.shade.mj dependency-service 1.0 ================================================ FILE: src/it/projects/MSHADE-313_minimized-services/used-service/src/main/java/SomeReferencedClass.java ================================================ /* * 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.ServiceLoader; public class SomeReferencedClass { { ServiceLoader.load( DependencyServiceInterface.class ); } } ================================================ FILE: src/it/projects/MSHADE-313_minimized-services/used-service/src/main/java/SomeServiceClass.java ================================================ /* * 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 SomeServiceClass implements SomeServiceInterface { private static SomeReferencedClass anEssentialDependency; } ================================================ FILE: src/it/projects/MSHADE-313_minimized-services/used-service/src/main/java/SomeServiceInterface.java ================================================ /* * 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 interface SomeServiceInterface { } ================================================ FILE: src/it/projects/MSHADE-313_minimized-services/used-service/src/main/java/SomeUnreferencedClass.java ================================================ /* * 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 SomeUnreferencedClass { } ================================================ FILE: src/it/projects/MSHADE-313_minimized-services/used-service/src/main/resources/META-INF/services/SomeServiceInterface ================================================ # # 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. # SomeServiceClass # Please do not remove comments or whitespace; they are part of the IT test. ================================================ FILE: src/it/projects/MSHADE-313_minimized-services/verify.bsh ================================================ /* * 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.io.*; 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" }; String[] unwanted = { // Unused SPI config files are not removed //"META-INF/services/UnusedServiceInterface", "UnusedServiceInterface.class", "UnusedServiceClass.class", "SomeUnreferencedClass.class", "DependencyUnreferencedClass.class" }; JarFile jarFile = new JarFile( new File( basedir, "test/target/test-1.0.jar" ) ); for ( String path : wanted ) { if ( jarFile.getEntry( path ) == null ) { throw new IllegalStateException( "wanted path is missing: " + path ); } } for ( String path : unwanted ) { if ( jarFile.getEntry( path ) != null ) { throw new IllegalStateException( "unwanted path is present: " + path ); } } jarFile.close(); ================================================ FILE: src/it/projects/MSHADE-316/dependency/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.mj dependency 1.0 ================================================ FILE: src/it/projects/MSHADE-316/dependency/src/main/java/SomeUnusedClass.java ================================================ /* * 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 SomeUnusedClass { } ================================================ FILE: src/it/projects/MSHADE-316/dependency/src/main/java/SomeUsedClass.java ================================================ /* * 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.ServiceLoader; public class SomeUsedClass { } ================================================ FILE: src/it/projects/MSHADE-316/dependency/src/main/java/x/y/z/AnotherExemptedClass.java ================================================ /* * 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 x.y.z; public class AnotherExemptedClass { } ================================================ FILE: src/it/projects/MSHADE-316/dependency/src/main/java/x/y/z/SomeDependencyOfExemptedClass.java ================================================ /* * 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 x.y.z; public class SomeDependencyOfExemptedClass { } ================================================ FILE: src/it/projects/MSHADE-316/dependency/src/main/java/x/y/z/SomeExemptedClass.java ================================================ /* * 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 x.y.z; public class SomeExemptedClass { public SomeDependencyOfExemptedClass essentialDependency; } ================================================ FILE: src/it/projects/MSHADE-316/invoker.properties ================================================ # 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. # jdependency-2.6.0 needs Java 8+ invoker.java.version = 1.8+ ================================================ FILE: src/it/projects/MSHADE-316/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.mj aggregate 1.0 pom MSHADE-316 Prevent minimizeJar from excluding classes explicitly exempted. dependency test ================================================ FILE: src/it/projects/MSHADE-316/test/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.mj test 1.0 org.apache.maven.its.shade.mj dependency 1.0 org.apache.maven.plugins maven-compiler-plugin @version.maven-compiler-plugin@ org.apache.maven.plugins maven-shade-plugin @project.version@ attach-shade package shade false true org.apache.maven.its.shade.mj:dependency false **/SomeExempted* **\AnotherExempted* ================================================ FILE: src/it/projects/MSHADE-316/test/src/main/java/Main.java ================================================ /* * 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 SomeUsedClass essentialDependency; public static void main( String[] args ) throws ClassNotFoundException { Class.forName( "x.y.z.SomeExemptedClass" ); Class.forName( "x.y.z.AnotherExemptedClass" ); } } ================================================ FILE: src/it/projects/MSHADE-316/verify.bsh ================================================ /* * 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.io.*; import java.util.jar.*; String[] wanted = { "Main.class", "SomeUsedClass.class", "x/y/z/SomeExemptedClass.class", "x/y/z/AnotherExemptedClass.class", "x/y/z/SomeDependencyOfExemptedClass.class" }; String[] unwanted = { "SomeUnusedClass.class" }; JarFile jarFile = new JarFile( new File( basedir, "test/target/test-1.0.jar" ) ); for ( String path : wanted ) { if ( jarFile.getEntry( path ) == null ) { throw new IllegalStateException( "wanted path is missing: " + path ); } } for ( String path : unwanted ) { if ( jarFile.getEntry( path ) != null ) { throw new IllegalStateException( "unwanted path is present: " + path ); } } jarFile.close(); ================================================ FILE: src/it/projects/MSHADE-340_shadedTestJarArtifactAttached/api/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.stj mshade-340-parent 1.0 mshade-340-api ================================================ FILE: src/it/projects/MSHADE-340_shadedTestJarArtifactAttached/api/src/main/java/Api.java ================================================ /* * 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. */ /** * Production API class. */ public class Api { } ================================================ FILE: src/it/projects/MSHADE-340_shadedTestJarArtifactAttached/api/src/test/java/ApiTest.java ================================================ /* * 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. */ /** * Test API class. */ public class ApiTest { public static void main(String[] args) { new Api(); } } ================================================ FILE: src/it/projects/MSHADE-340_shadedTestJarArtifactAttached/impl/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.stj mshade-340-parent 1.0 mshade-340-impl org.apache.maven.its.shade.stj mshade-340-api org.apache.maven.its.shade.stj mshade-340-api test-jar ================================================ FILE: src/it/projects/MSHADE-340_shadedTestJarArtifactAttached/impl/src/main/java/Impl.java ================================================ /* * 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. */ /** * Production implementation class. */ public class Impl extends Api { } ================================================ FILE: src/it/projects/MSHADE-340_shadedTestJarArtifactAttached/impl/src/test/java/ImplTest.java ================================================ /* * 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. */ /** * Test implementation class. */ public class ImplTest extends ApiTest { public static void main(String[] args) { new Impl(); } } ================================================ FILE: src/it/projects/MSHADE-340_shadedTestJarArtifactAttached/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.stj mshade-340-parent pom 1.0 api impl uber uber-user org.apache.maven.its.shade.stj mshade-340-api 1.0 org.apache.maven.its.shade.stj mshade-340-api 1.0 test-jar test org.apache.maven.its.shade.stj mshade-340-impl 1.0 org.apache.maven.its.shade.stj mshade-340-impl 1.0 test-jar test org.apache.maven.its.shade.stj mshade-340-uber 1.0 jack-of-all org.apache.maven.its.shade.stj mshade-340-uber 1.0 test-jar jack-of-all-tests test maven-source-plugin default-source jar-no-fork test-jar-no-fork maven-jar-plugin default-jar jar test-jar ================================================ FILE: src/it/projects/MSHADE-340_shadedTestJarArtifactAttached/uber/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.stj mshade-340-parent 1.0 mshade-340-uber org.apache.maven.its.shade.stj mshade-340-api org.apache.maven.its.shade.stj mshade-340-api test-jar org.apache.maven.its.shade.stj mshade-340-impl org.apache.maven.its.shade.stj mshade-340-impl test-jar maven-shade-plugin @project.version@ shade true jack-of-all true true true ================================================ FILE: src/it/projects/MSHADE-340_shadedTestJarArtifactAttached/uber/src/main/java/Uber.java ================================================ /* * 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. */ /** * Proper class of the uber project. */ public class Uber { } ================================================ FILE: src/it/projects/MSHADE-340_shadedTestJarArtifactAttached/uber/src/test/java/UberTest.java ================================================ /* * 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. */ /** * Proper test of the uber project. */ public class UberTest { } ================================================ FILE: src/it/projects/MSHADE-340_shadedTestJarArtifactAttached/uber-user/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.stj mshade-340-parent 1.0 mshade-340-uber-user org.apache.maven.its.shade.stj mshade-340-uber jar jack-of-all org.apache.maven.its.shade.stj mshade-340-uber test-jar jack-of-all-tests maven-shade-plugin @project.version@ shade true jack-of-all true true true ================================================ FILE: src/it/projects/MSHADE-340_shadedTestJarArtifactAttached/uber-user/src/main/java/UberUser.java ================================================ /* * 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 UberUser { Api api; Impl impl; } ================================================ FILE: src/it/projects/MSHADE-340_shadedTestJarArtifactAttached/uber-user/src/test/java/UberUserTest.java ================================================ /* * 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. */ /** * MSHADE-340 The fact that this class compiles verifies the fix. * Without the fix, the (test) dependency cannot be found and compilation fails. * Even though the file exists, it is not correctly attached to the project. */ public class UberUserTest { UberUser uberUser; ApiTest apiTest; ImplTest implTest; } ================================================ FILE: src/it/projects/MSHADE-340_shadedTestJarArtifactAttached/verify.groovy ================================================ /* * 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 originalUberJar = new File( basedir, "uber/target/mshade-340-uber-1.0.jar" ) def jackOfAllUberJar = new File( basedir, "uber/target/mshade-340-uber-1.0-jack-of-all.jar" ) def originalUberTestJar = new File ( basedir, "uber/target/mshade-340-uber-1.0-tests.jar" ) def jackOfAllUberTestJar = new File ( basedir, "uber/target/mshade-340-uber-1.0-jack-of-all-tests.jar" ) def originalUberSourcesJar = new File( basedir, "uber/target/mshade-340-uber-1.0-sources.jar" ) def jackOfAllUberSourcesJar = new File( basedir, "uber/target/mshade-340-uber-1.0-jack-of-all-sources.jar" ) def originalUberTestSourcesJar = new File ( basedir, "uber/target/mshade-340-uber-1.0-test-sources.jar" ) def jackOfAllUberTestSourcesJar = new File ( basedir, "uber/target/mshade-340-uber-1.0-jack-of-all-test-sources.jar" ) assert originalUberJar.exists() assert jackOfAllUberJar.exists() assert originalUberTestJar.exists() assert jackOfAllUberTestJar.exists() assert originalUberSourcesJar.exists() assert jackOfAllUberSourcesJar.exists() assert originalUberTestSourcesJar.exists() assert jackOfAllUberTestSourcesJar.exists() def originalUberJarFile = new java.util.jar.JarFile( originalUberJar ) try { assert null == originalUberJarFile.getJarEntry( "Api.class" ) assert null == originalUberJarFile.getJarEntry( "Impl.class" ) assert null != originalUberJarFile.getJarEntry( "Uber.class" ) } finally { originalUberJarFile.close() } def jackOfAllUberJarFile = new java.util.jar.JarFile( jackOfAllUberJar ) try { assert null != jackOfAllUberJarFile.getJarEntry( "Api.class" ) assert null != jackOfAllUberJarFile.getJarEntry( "Impl.class" ) assert null != jackOfAllUberJarFile.getJarEntry( "Uber.class" ) } finally { jackOfAllUberJarFile.close() } def originalUberTestJarFile = new java.util.jar.JarFile( originalUberTestJar ) try { assert null == originalUberTestJarFile.getJarEntry( "ApiTest.class" ) assert null == originalUberTestJarFile.getJarEntry( "ImplTest.class" ) assert null != originalUberTestJarFile.getJarEntry( "UberTest.class" ) } finally { originalUberTestJarFile.close() } def jackOfAllUberTestJarFile = new java.util.jar.JarFile( jackOfAllUberTestJar ) try { assert null != jackOfAllUberTestJarFile.getJarEntry( "ApiTest.class" ) assert null != jackOfAllUberTestJarFile.getJarEntry( "ImplTest.class" ) assert null != jackOfAllUberTestJarFile.getJarEntry( "UberTest.class" ) } finally { jackOfAllUberTestJarFile.close() } def originalUberSourcesJarFile = new java.util.jar.JarFile( originalUberSourcesJar ) try { assert null == originalUberSourcesJarFile.getJarEntry( "Api.java" ) assert null == originalUberSourcesJarFile.getJarEntry( "Impl.java" ) assert null != originalUberSourcesJarFile.getJarEntry( "Uber.java" ) } finally { originalUberSourcesJarFile.close() } def jackOfAllUberSourcesJarFile = new java.util.jar.JarFile( jackOfAllUberSourcesJar ) try { assert null != jackOfAllUberSourcesJarFile.getJarEntry( "Api.java" ) assert null != jackOfAllUberSourcesJarFile.getJarEntry( "Impl.java" ) assert null != jackOfAllUberSourcesJarFile.getJarEntry( "Uber.java" ) } finally { jackOfAllUberSourcesJarFile.close() } def originalUberTestSourcesJarFile = new java.util.jar.JarFile( originalUberTestSourcesJar ) try { assert null == originalUberTestSourcesJarFile.getJarEntry( "ApiTest.java" ) assert null == originalUberTestSourcesJarFile.getJarEntry( "ImplTest.java" ) assert null != originalUberTestSourcesJarFile.getJarEntry( "UberTest.java" ) } finally { originalUberTestSourcesJarFile.close() } def jackOfAllUberTestSourcesJarFile = new java.util.jar.JarFile( jackOfAllUberTestSourcesJar ) try { assert null != jackOfAllUberTestSourcesJarFile.getJarEntry( "ApiTest.java" ) assert null != jackOfAllUberTestSourcesJarFile.getJarEntry( "ImplTest.java" ) assert null != jackOfAllUberTestSourcesJarFile.getJarEntry( "UberTest.java" ) } finally { jackOfAllUberTestSourcesJarFile.close() } ================================================ FILE: src/it/projects/MSHADE-351/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.srt test 1.0 MSHADE-351 Test the merging of META-INF/services/** entries. org.apache.maven.its.shade.srt one 0.1 org.apache.maven.its.shade.srt two 0.1 org.apache.maven.plugins maven-shade-plugin @project.version@ attach-shade shade false ================================================ FILE: src/it/projects/MSHADE-351/verify.bsh ================================================ /* * 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.io.*; import java.util.jar.*; import org.codehaus.plexus.util.*; JarFile jarFile = new JarFile( new File( basedir, "target/test-1.0.jar" ) ); JarEntry jarEntry = jarFile.getEntry( "META-INF/services/org.apache.maven.Shade" ); String service = IOUtil.toString( jarFile.getInputStream( jarEntry ), "UTF-8" ); jarFile.close(); ================================================ FILE: src/it/projects/MSHADE-36-inject-dep-reduced-pom-in-final/invoker.properties ================================================ # 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.goals = clean package ================================================ FILE: src/it/projects/MSHADE-36-inject-dep-reduced-pom-in-final/pom.xml ================================================ 4.0.0 org.apache.maven.plugins.shade.its shade-parent 1.0 ../setup-parent org.apache.maven.its.shade.drp test 1.0 jar MSHADE-36 Test to see that the dependency-reduced-pom.xml is injected into the final jar instead of the original pom.xml junit junit 4.13.2 org.codehaus.plexus plexus-utils 3.5.1 org.apache.maven.plugins maven-compiler-plugin @version.maven-compiler-plugin@ org.apache.maven.plugins maven-shade-plugin @project.version@ attach-shade package shade true true true org.codehaus.plexus com.example.shaded.org.codehaus.plexus junit:junit org.codehaus.plexus:plexus-utils ================================================ FILE: src/it/projects/MSHADE-36-inject-dep-reduced-pom-in-final/src/main/java/com/example/Main.java ================================================ /* * 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 com.example; import org.codehaus.plexus.util.StringUtils; public class Main { public static void main( String[] args ) { System.out.println( "Hello World!" + ( isEmpty("foo") ? " is empty!" : " -- ") ); } public static boolean isEmpty( String input ) { return StringUtils.isEmpty( input ); } } ================================================ FILE: src/it/projects/MSHADE-36-inject-dep-reduced-pom-in-final/verify.bsh ================================================ /* * 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.io.*; import java.util.jar.*; import java.util.Arrays; import org.codehaus.plexus.util.*; String[] wanted = { "com/example/Main.class", "junit/runner/logo.gif", "com/example/shaded/org/codehaus/plexus/util/StringUtils.class", }; String[] unwanted = { "junit/textui/TestRunner.class", "org/codehaus/plexus/util/StringUtils.class", }; JarFile jarFile = null; try { jarFile = new JarFile ( new File( basedir, "target/test-1.0.jar" ) ); for ( String path:wanted ) { if ( jarFile.getEntry( path ) == null ) { throw new IllegalStateException( "wanted path is missing: "+path ); } } for ( String path:unwanted ) { if ( jarFile.getEntry( path ) != null ) { throw new IllegalStateException ( "unwanted path is present: "+path ); } } JarEntry jarEntry = jarFile.getEntry( "META-INF/maven/org.apache.maven.its.shade.drp/test/pom.xml" ); String pomFile = IOUtil.toString( jarFile.getInputStream( jarEntry ), "UTF-8" ); if ( pomFile.contains( "org.codehaus.plexus" ) ) { throw new IllegalStateException( "The pom.xml still contains a reference to the org.codehaus.plexus dependency" ); } } finally { if ( jarFile != null ) { jarFile.close(); } } ================================================ FILE: src/it/projects/MSHADE-363_old-Transformer/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.pp mshade-363 1.0-SNAPSHOT check non-breaking change to ResourceTransformer's API support for Reproducible Builds in MSHADE-352 requires a new long time parameter to void processResource( String resource, InputStream is, List<Relocator> relocators, long time ) breaking old maven-shade-plugin extensions implementing interface without this parameter UTF-8 org.apache.maven.plugins maven-shade-plugin @project.version@ org.springframework.boot spring-boot-maven-plugin 1.5.22.RELEASE use-extra-resource-transformer package shade Message.properties ================================================ FILE: src/it/projects/MSHADE-363_old-Transformer/src/main/resources/Message.properties ================================================ # 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. one = one ================================================ FILE: src/it/projects/MSHADE-363_old-plugin/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.pp mshade-363-use-custom 1.0-SNAPSHOT check new ReproducibleResourceTransformer API can be used with older shade plugin if new extensions cannot be used with older shade plugin, it will add user-visible constraints... UTF-8 org.apache.maven.plugins maven-shade-plugin 3.2.2 org.apache.maven.plugins maven-shade-plugin @project.version@ tests use-extra-resource-transformer package shade ================================================ FILE: src/it/projects/MSHADE-363_old-plugin/src/main/resources/Message.properties ================================================ # 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. one = one ================================================ FILE: src/it/projects/MSHADE-373/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.mt test 1.0 jar MSHADE-373 Test that reproduces the issue described in MSHADE-373. org.apache.maven.plugins maven-shade-plugin @project.version@ org.apache.maven.plugins maven-compiler-plugin @version.maven-compiler-plugin@ org.apache.maven.plugins maven-install-plugin @version.maven-install-plugin@ org.apache.maven.plugins maven-jar-plugin @version.maven-jar-plugin@ org.apache.maven.Main PASSED PASSED org.apache.maven.plugins maven-resources-plugin @version.maven-resources-plugin@ org.apache.maven.plugins maven-shade-plugin @project.version@ attach-shade package shade true true false SET sources-jar FAILED org.apache.maven.plugins maven-surefire-plugin @version.maven-surefire@ ================================================ FILE: src/it/projects/MSHADE-373/verify.bsh ================================================ /* * 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.io.*; import java.util.jar.*; // NOTE: We deliberately use JarInputStream and not JarFile here! Manifest extractManifest(name) { file = new File( basedir, "target/" + name ); if ( !file.exists() ) { throw new IllegalStateException( "No file '" + file + "'" ); } JarInputStream jarStream = new JarInputStream( new FileInputStream( file ) ); Manifest mf = jarStream.getManifest(); jarStream.close(); return mf; } void assertsEntries( name, expectedTestEntry, expectedOriginalEntry, expectedCustomEntry ) { attributes = extractManifest( name ).getMainAttributes(); if ( !Objects.equals( expectedTestEntry, attributes.getValue( "Test-Entry" ) ) ) { throw new IllegalStateException( "Test-Entry should have been '" + expectedTestEntry + "' in " + name + ": " + attributes.entrySet() ); } if ( !Objects.equals( expectedOriginalEntry, attributes.getValue( "Original-Entry" ) ) ) { throw new IllegalStateException( "Original-Entry should have been '" + expectedOriginalEntry + "' in " + name + ": " + attributes.entrySet() ); } if ( !Objects.equals( expectedCustomEntry, attributes.getValue( "Custom-Entry" ) ) ) { throw new IllegalStateException( "Custom-Entry should have been '" + expectedCustomEntry + "' in " + name + ": " + attributes.entrySet() ); } } assertsEntries( "test-1.0.jar", "PASSED", "PASSED", "SET" ); assertsEntries( "test-1.0-sources.jar", "FAILED", null, null ); // specific config assertsEntries( "test-1.0-tests.jar", "PASSED", "PASSED", "SET" ); // inherits from the default transformer ================================================ FILE: src/it/projects/MSHADE-382_skip_execution/invoker.properties ================================================ # 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 = 1.8+ ================================================ FILE: src/it/projects/MSHADE-382_skip_execution/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.mj skip-execution 1.0 MSHADE-382 Skip shading org.apache.maven.plugins maven-shade-plugin @project.version@ create-shaded-artifact package shade true ================================================ FILE: src/it/projects/MSHADE-382_skip_execution/verify.groovy ================================================ /* * 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. */ assert !(new File( basedir, "target/original-skip-execution-1.0.jar" ).exists()) : "Shading was not skipped." ================================================ FILE: src/it/projects/MSHADE-390-sisu-index/invoker.properties ================================================ # 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.goals=clean package ================================================ FILE: src/it/projects/MSHADE-390-sisu-index/one/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.pp mshade-390 1.0-SNAPSHOT one ================================================ FILE: src/it/projects/MSHADE-390-sisu-index/one/src/main/java/org/apache/one/One.java ================================================ package org.apache.one; public class One { } ================================================ FILE: src/it/projects/MSHADE-390-sisu-index/one/src/main/resources/META-INF/sisu/javax.inject.Named ================================================ org.apache.one.One ================================================ FILE: src/it/projects/MSHADE-390-sisu-index/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.pp mshade-390 1.0-SNAPSHOT pom UTF-8 org.apache.maven.its.shade.pp one ${project.version} one two ================================================ FILE: src/it/projects/MSHADE-390-sisu-index/two/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.pp mshade-390 1.0-SNAPSHOT two org.apache.maven.its.shade.pp one org.apache.maven.plugins maven-shade-plugin @project.version@ attach-shade package shade false org.apache.one org.apache.two.org.apache.one ================================================ FILE: src/it/projects/MSHADE-390-sisu-index/two/src/main/java/org/apache/two/Two.java ================================================ package org.apache.two; public class Two { } ================================================ FILE: src/it/projects/MSHADE-390-sisu-index/two/src/main/resources/META-INF/sisu/javax.inject.Named ================================================ org.apache.two.Two ================================================ FILE: src/it/projects/MSHADE-390-sisu-index/verify.groovy ================================================ /* * 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, "two/target/two-1.0-SNAPSHOT.jar")) def jarEntry = jarFile.getJarEntry("META-INF/sisu/javax.inject.Named") def merged = jarFile.getInputStream(jarEntry).getText() assert merged.contains( 'org.apache.two.org.apache.one.One' ) assert merged.contains( 'org.apache.two.Two' ) ================================================ FILE: src/it/projects/MSHADE-391_noRelocationKeepOriginalClasses/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.csj mshade-391 1.0 https://issues.apache.org/jira/browse/MSHADE-391 ASM-processed classes should not be written to the shaded JAR if they have not been relocated and do not refer to relocated classes either. In that case, the user expects to retain the original classes. commons-io commons-io 2.13.0 commons-lang commons-lang 2.6 compile org.apache.maven.plugins maven-shade-plugin @project.version@ shade shade org.apache.commons.io org.shaded.commons.io *:* META-INF/** ================================================ FILE: src/it/projects/MSHADE-391_noRelocationKeepOriginalClasses/verify.groovy ================================================ /* * 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.security.MessageDigest import java.util.jar.JarFile def originalChecksumsMD5 = [ 'ArrayUtils.class' : '4644ce91f5dbf1172f3bc2eafa1220bc', 'BitField.class' : 'ec5d367938cb9f59912fafbe708112fa', 'BooleanUtils.class' : 'c321cc00995b4e81162cec9366406817', 'builder/CompareToBuilder.class' : '70c085203ca3506fb0fbd1eed8de9ffe', 'builder/EqualsBuilder.class' : 'e538ada29bf74d053b4174c6d0338c29', 'builder/HashCodeBuilder.class' : '76e129cfdadefc856588351c830570e6', 'builder/IDKey.class' : 'fa08336106e492b5ac9f9901bd7ec690', 'builder/ReflectionToStringBuilder.class' : '5a30e353b9f1bd0c9d8ed547c3ef576d', 'builder/StandardToStringStyle.class' : 'bd26865d3f4f0e3a0f24efe00897f4f3', 'builder/ToStringBuilder.class' : '8493114752dd3552e21eba63343e6558', 'builder/ToStringStyle$DefaultToStringStyle.class' : 'e4d42ea42ea43ad971fe5d33624063a6', 'builder/ToStringStyle$MultiLineToStringStyle.class' : '3f2306c0f664229419dad8bfcfb0142d', 'builder/ToStringStyle$NoFieldNameToStringStyle.class': '9ed4e831c533c0fc98f3583c1e6fda31', 'builder/ToStringStyle$ShortPrefixToStringStyle.class': '4aa105e83bcd37a06f6d598a9c59d91c', 'builder/ToStringStyle$SimpleToStringStyle.class' : 'c156f9816faa3da7b664df81fe811b50', 'builder/ToStringStyle.class' : '4088eef1b6a33ff2b6483b2f79461364', 'CharEncoding.class' : '68b058ceea276d04247aff21ef7dbb63', 'CharRange$1.class' : 'b3034e9540791bc9ce371e75d0ba8785', 'CharRange$CharacterIterator.class' : 'fdb6df8bbf32f88f88749ade8552d081', 'CharRange.class' : 'a6b95e2ed34c8e46a9889568e56bacb8', 'CharSet.class' : '4e0df369374e877afefc76153797cffd', 'CharSetUtils.class' : '94a3d9c03ce37f671e5bdbb6605fe18b', 'CharUtils.class' : '5706b8e0802f818efac9e5c6c203d428', 'ClassUtils.class' : '09bc083bfe4f11d562d32c14b88b5a8e', 'Entities$ArrayEntityMap.class' : 'ff3a4211ef9b3c463eb79c1d04ad8d25', 'Entities$BinaryEntityMap.class' : '12b7fdc0621bea444f687950466fd89b', 'Entities$EntityMap.class' : '8e35cd73a7f6d80f45b328c228bcbc7d', 'Entities$HashEntityMap.class' : 'e8ab521f1a3fdca02c7e44daa33f7688', 'Entities$LookupEntityMap.class' : '1e59392ae388c8da917881f9f8b4998d', 'Entities$MapIntMap.class' : 'ce32c8d2649bbf479e7c511d110bf9c2', 'Entities$PrimitiveEntityMap.class' : '110a8762a727788dc038d47385a55eaf', 'Entities$TreeEntityMap.class' : '2a51fb240cd9cc51dbf249ebc20c5639', 'Entities.class' : '8d0f106f7591b55d0b57927d0fcce871', 'enum/Enum$Entry.class' : 'bb9c0b1ecfcd16e873d180ce20129e9e', 'enum/Enum.class' : 'fda3012c2bc97b7d0425057b8d98ca30', 'enum/EnumUtils.class' : 'd9d966cd69bef5a14d9c514a3aec8a1d', 'enum/ValuedEnum.class' : '6196dd12bd0b6debcef93f78cae0f094', 'enums/Enum$Entry.class' : 'a625be33cd61f7e00da41d868ac5fbde', 'enums/Enum.class' : '5769c6367611bdeaab3536c979e931ec', 'enums/EnumUtils.class' : '5c4c227735393bcd5d550172afe0d1e7', 'enums/ValuedEnum.class' : '7cc89eafa3f01eca7f989e4a95880484', 'exception/CloneFailedException.class' : 'a1d1fe5140c39f1d9c13b9716df320e0', 'exception/ExceptionUtils.class' : 'bfbbc6b82e778a91c9ac885a582aa87a', 'exception/Nestable.class' : 'cb37cc4f6aa95ddc1e08e24dfdb1faeb', 'exception/NestableDelegate.class' : '72610ad6e1acd693a73bd169c4c2fe66', 'exception/NestableError.class' : 'e9dec41924015b2a37fcc724994601d7', 'exception/NestableException.class' : 'f88cb396c859f785b13272236dd2d14a', 'exception/NestableRuntimeException.class' : 'b3712109e98e7dfe916c028944be71a2', 'IllegalClassException.class' : '592efb0cd4c69c78890f51e5aefd5323', 'IncompleteArgumentException.class' : 'c65def57686f1433fec9de1a53d7e968', 'IntHashMap$Entry.class' : '312431259a720c5cc59919164e1f6f94', 'IntHashMap.class' : '09e0c9e37e06edc13912e9179d123df2', 'LocaleUtils.class' : 'ba8b698331343045e4714ab276d84df3', 'math/DoubleRange.class' : 'ae74dc56efa1d6608a34cd87326775df', 'math/FloatRange.class' : 'ca15b57ff629ad21c135daa3af4ae748', 'math/Fraction.class' : '966d7dba648d56d40415f1d76eb61f22', 'math/IEEE754rUtils.class' : '904f0342faa83dc32aa3ce09b570d6e6', 'math/IntRange.class' : '1a08884805a90e85a4af5f38f5c1d3ae', 'math/JVMRandom.class' : '1c38d4c2b8dcd9feee7ca4affc945ef9', 'math/LongRange.class' : 'ebc6dbf88a701e592764d635234eeec4', 'math/NumberRange.class' : '78de0d669bc79bba406be19c5fdd0abb', 'math/NumberUtils.class' : '5ae54b27c20fa65144d64c65449aaa89', 'math/RandomUtils.class' : '40155ad57c6f32460e0f32f3db22b173', 'math/Range.class' : 'dab8235e8a5cc7d9b9103f416478f39a', 'mutable/Mutable.class' : '0c3515bc904e276c781486c67ec34e71', 'mutable/MutableBoolean.class' : '1f5979176185bf9638ca60d15526b45e', 'mutable/MutableByte.class' : 'd458d842df3c178069a7969fc9f6af38', 'mutable/MutableDouble.class' : '1c32ae0b6cdfc00d48280164a6ef8e9b', 'mutable/MutableFloat.class' : 'f5a58dc62a9f95081f678db598f9513d', 'mutable/MutableInt.class' : '2350cc67b99f6427d404ea7233d94664', 'mutable/MutableLong.class' : '7459b453c34cfe6beeb877bcc5fc4e81', 'mutable/MutableObject.class' : 'f16ed36d34163fd6219c59fffdc02760', 'mutable/MutableShort.class' : 'e3192bee99861e409c941bc2a5be9add', 'NotImplementedException.class' : '45f4bfa15f637b7ac8fba0ea5af9a981', 'NullArgumentException.class' : '206902af1b00283b40b258b28385f63b', 'NumberRange.class' : '54fbe10934f95117f8d3f0c0546b56c7', 'NumberUtils.class' : '2de64e30b07a36e11f095f3146f16aa0', 'ObjectUtils$Null.class' : '1138f88d2527f63458eaa56c959f818c', 'ObjectUtils.class' : '40483af3c9a0cdcb5ee0df43c1fa3ae8', 'RandomStringUtils.class' : '1a4f147bab572b579db352d06979ce0a', 'reflect/ConstructorUtils.class' : '96b06ea51ec96064b7d881975dffc8bb', 'reflect/FieldUtils.class' : 'f37be95c51f707ea1dd965d02f20f540', 'reflect/MemberUtils.class' : '9fe7b0a7c664458058668c5400a2139b', 'reflect/MethodUtils.class' : '4d7781bf651d8a1f750ba75f628f45e4', 'SerializationException.class' : '7eaeab8f24eeed40e089d4abeffc3ad4', 'SerializationUtils.class' : '32062839391b9896caa63067a4040a6c', 'StringEscapeUtils.class' : 'c1fe975a05f7d14823d3dbce29c23bb2', 'StringUtils.class' : 'bb4c964dd2c5057d3a8f282ea381c05d', 'SystemUtils.class' : '74492426bb3b60ea1e3c3816b955f40f', 'text/CompositeFormat.class' : 'dd2b0fc2a4784eb07754f8271d758ba5', 'text/ExtendedMessageFormat.class' : 'eb32c6eb2f83e784c5479a00edb9d35d', 'text/FormatFactory.class' : 'b8b2a7245d750929eebf82c59a34af4a', 'text/StrBuilder$StrBuilderReader.class' : 'b67a32739b45226ae25297150f4a3672', 'text/StrBuilder$StrBuilderTokenizer.class' : '22d8351ad6688698c281e980b5e2aef0', 'text/StrBuilder$StrBuilderWriter.class' : '911b13b209c459ab0e649fcf16da119f', 'text/StrBuilder.class' : '0daf9125d2bb85d7be8f0930d65a8881', 'text/StrLookup$MapStrLookup.class' : '9468c0e1dbf42c9842f57662ab65a295', 'text/StrLookup.class' : '5755445f8e6509993c501450b4ca0283', 'text/StrMatcher$CharMatcher.class' : 'c40179bba463256255193200fad920b1', 'text/StrMatcher$CharSetMatcher.class' : '93b22e1f09237f052c32ec202d95dd16', 'text/StrMatcher$NoMatcher.class' : '1bf4cce48a7fc1abd12ce0ddc32a0f21', 'text/StrMatcher$StringMatcher.class' : 'e223633d564e39846dd74ce6aa343a1d', 'text/StrMatcher$TrimMatcher.class' : '681a4bd78f7f2c5fd74a99370ad4b20b', 'text/StrMatcher.class' : 'f5a6d712ffd750ca1c7613b394ea3f22', 'text/StrSubstitutor.class' : '1cfa5ab4e0990595dec646037c5967a9', 'text/StrTokenizer.class' : 'bf73deb873f50e8ba34de3998e2972c4', 'time/DateFormatUtils.class' : 'fb537b3f1a510ac0c52804e4aff27763', 'time/DateUtils$DateIterator.class' : 'ba97d5b0027fe3e5a591f07864e44bbb', 'time/DateUtils.class' : 'df75657605e945dbbcbe886704470137', 'time/DurationFormatUtils$Token.class' : 'ed64a1f1a2a41e56ae50309a1fde175c', 'time/DurationFormatUtils.class' : 'e393be23cc1ab1ff59091a1b83cc9bbd', 'time/FastDateFormat$CharacterLiteral.class' : '249c346d9821e022bdb659c222dbf644', 'time/FastDateFormat$NumberRule.class' : 'c41df9bc3bdff9cb4d68dd74885616b6', 'time/FastDateFormat$PaddedNumberField.class' : '4cd9e98b2afc00b17d0d2038b397de24', 'time/FastDateFormat$Pair.class' : '8a934ec5d93793facff76c7e8cf3280e', 'time/FastDateFormat$Rule.class' : '442ea43c86a34ef4a5d416d3dead1ada', 'time/FastDateFormat$StringLiteral.class' : '4d61134d7b4947e972418208f946417c', 'time/FastDateFormat$TextField.class' : '6894c0815fcc85c5ceb9a22df07ab4fd', 'time/FastDateFormat$TimeZoneDisplayKey.class' : '20a24c7f131f38d1e4deb74572c10f45', 'time/FastDateFormat$TimeZoneNameRule.class' : '529cab8e6727bf6f67f921060d5be564', 'time/FastDateFormat$TimeZoneNumberRule.class' : '0217783a5cac5dc5ab9e32c7c1b82d63', 'time/FastDateFormat$TwelveHourField.class' : '17aa8c1efb59e32ab1c3309a315a2d4a', 'time/FastDateFormat$TwentyFourHourField.class' : 'a1a4a9dae07bb5f8406e4b21d36fe6a3', 'time/FastDateFormat$TwoDigitMonthField.class' : 'c5ace49716048e8f189fc1b24bad9a96', 'time/FastDateFormat$TwoDigitNumberField.class' : '92b23f96a47805d2f35df7436e268186', 'time/FastDateFormat$TwoDigitYearField.class' : '876f335aad5398564e7065a6dc049e35', 'time/FastDateFormat$UnpaddedMonthField.class' : '4471d8973417c87437795a7c14f6e1d9', 'time/FastDateFormat$UnpaddedNumberField.class' : '26bc03b8208bb6e1f5d815029165fde9', 'time/FastDateFormat.class' : '81458555c631fd1cd7d1c7b580a252d0', 'time/StopWatch.class' : 'c9cd6ccf4eb13950ce32bccc4229d3d2', 'UnhandledException.class' : '01110b3515eb3f010cbc0485f1cb9b02', 'Validate.class' : 'ee955facbc21ae85ba81f2ca10c2dbb9', 'WordUtils.class' : '771ffae0f501e8378cda1a516bda46b2', ] def jarFile = new JarFile( new File( basedir, "target/mshade-391-1.0.jar" ) ) try { originalChecksumsMD5.each { checksumEntry -> def entryPath = "org/apache/commons/lang/$checksumEntry.key" def bytes = jarFile.getInputStream(jarFile.getJarEntry(entryPath)).bytes def jarEntryMD5 = MessageDigest.getInstance("MD5").digest(bytes).encodeHex().toString() assert checksumEntry.value == jarEntryMD5 } true } finally { jarFile.close() } ================================================ FILE: src/it/projects/MSHADE-400_self-minimized-services/invoker.properties ================================================ # 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. # jdependency-2.6.0 needs Java 8+ invoker.java.version = 1.8+ ================================================ FILE: src/it/projects/MSHADE-400_self-minimized-services/pom.xml ================================================ 4.0.0 org.acme module-with-services 1.0 8 8 org.apache.maven.plugins maven-shade-plugin @project.version@ shade package shade true org.acme.Application ================================================ FILE: src/it/projects/MSHADE-400_self-minimized-services/src/main/java/org/acme/Application.java ================================================ /* * 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 ); } } ================================================ FILE: src/it/projects/MSHADE-400_self-minimized-services/src/main/java/org/acme/UnusedClass.java ================================================ /* * 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 { } ================================================ FILE: src/it/projects/MSHADE-400_self-minimized-services/src/main/java/org/acme/UnusedService.java ================================================ /* * 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(); } ================================================ FILE: src/it/projects/MSHADE-400_self-minimized-services/src/main/java/org/acme/UnusedServiceImplA.java ================================================ /* * 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() { } } ================================================ FILE: src/it/projects/MSHADE-400_self-minimized-services/src/main/java/org/acme/UnusedServiceImplB.java ================================================ /* * 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() { } } ================================================ FILE: src/it/projects/MSHADE-400_self-minimized-services/src/main/java/org/acme/UsedClass.java ================================================ /* * 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 { } ================================================ FILE: src/it/projects/MSHADE-400_self-minimized-services/src/main/java/org/acme/UsedService.java ================================================ /* * 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(); } ================================================ FILE: src/it/projects/MSHADE-400_self-minimized-services/src/main/java/org/acme/UsedServiceUnusedImpl.java ================================================ /* * 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() { } } ================================================ FILE: src/it/projects/MSHADE-400_self-minimized-services/src/main/java/org/acme/UsedServiceUsedImpl.java ================================================ /* * 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() { } } ================================================ FILE: src/it/projects/MSHADE-400_self-minimized-services/src/main/resources/META-INF/services/org.acme.UnusedService ================================================ # # 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. # # These services are defined, but not used in the entry point or any of its dependency classes org.acme.UnusedServiceUsedImplA org.acme.UnusedServiceUsedImplB ================================================ FILE: src/it/projects/MSHADE-400_self-minimized-services/src/main/resources/META-INF/services/org.acme.UsedService ================================================ # # 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. # org.acme.UsedServiceUsedImpl # This implementation is *not* used: # org.acme.UsedServiceUnusedImpl ================================================ FILE: src/it/projects/MSHADE-400_self-minimized-services/verify.bsh ================================================ /* * 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.io.*; import java.util.jar.*; String[] wanted = { "META-INF/services/org.acme.UsedService", "org/acme/Application.class", "org/acme/UsedClass.class", "org/acme/UsedService.class", "org/acme/UsedServiceUsedImpl.class" }; String[] unwanted = { // 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, "target/module-with-services-1.0.jar" ) ); for ( String path : wanted ) { if ( jarFile.getEntry( path ) == null ) { throw new IllegalStateException( "wanted path is missing: " + path ); } } for ( String path : unwanted ) { if ( jarFile.getEntry( path ) != null ) { throw new IllegalStateException( "unwanted path is present: " + path ); } } jarFile.close(); ================================================ FILE: src/it/projects/MSHADE-413-parallel/invoker.properties ================================================ # 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.timeoutInSeconds=60 invoker.goals = clean install -T2 -pl p1/ -pl p2/ ================================================ FILE: src/it/projects/MSHADE-413-parallel/p1/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.parallel mshade413-parent 1.0 mshade413-p1 1.0 MSHADE-413-p1 org.projectnessie nessie-spark-extensions-base 0.22.0 org.projectnessie nessie-spark-extensions-base 0.22.0 tests test org.apache.iceberg iceberg-spark3-runtime 0.13.1 test org.junit.jupiter junit-jupiter-api 5.8.2 test org.apache.maven.plugins maven-shade-plugin @project.version@ org.projectnessie package shade ================================================ FILE: src/it/projects/MSHADE-413-parallel/p2/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.parallel mshade413-parent 1.0 mshade413-p2 1.0 MSHADE-413-p2 org.projectnessie nessie-spark-extensions-base 0.22.0 org.projectnessie nessie-spark-extensions-base 0.22.0 tests test org.apache.iceberg iceberg-spark3-runtime 0.13.1 test org.junit.jupiter junit-jupiter-api 5.8.2 test org.apache.maven.plugins maven-shade-plugin @project.version@ org.projectnessie package shade ================================================ FILE: src/it/projects/MSHADE-413-parallel/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.parallel mshade413-parent 1.0 pom MSHADE-413 Test that shade works in two parallel project builds. p1 p2 ================================================ FILE: src/it/projects/MSHADE-420/invoker.properties ================================================ # 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.goals.1 = clean package -DfinalName=current-OS dependency:copy-dependencies invoker.mavenOpts.2=-Duser.timezone=Etc/UTC invoker.goals.2 = package -DfinalName=UTC invoker.mavenOpts.3=-Duser.timezone=Asia/Tokyo invoker.goals.3 = package -DfinalName=Tokyo invoker.mavenOpts.4=-Duser.timezone=Canada/Yukon invoker.goals.4 = package -DfinalName=Yukon ================================================ FILE: src/it/projects/MSHADE-420/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.parallel mshade420 1.0 MSHADE-420 Some jar entries are timezone-sensitive. net.java.dev.jna jna 5.13.0 org.apache.maven.plugins maven-shade-plugin @project.version@ shade ${finalName} net.java.dev.jna:jna META-INF/* **/*.class com/sun/jna/win32**/* org.apache.maven.plugins maven-dependency-plugin 3.5.0 copy-dependencies ================================================ FILE: src/it/projects/MSHADE-420/verify.groovy ================================================ /* * 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.security.MessageDigest import java.util.jar.JarFile String describeEntry(JarFile jar, String name, long time) { def entry = jar.getEntry(name) return String.format(" - %-47s: time = %d, lastModified = %s = diff %d min., extra = %b", name, entry.getTime(), entry.getLastModifiedTime().toString(), (long)((entry.getTime() / 1000L - time)/60L), entry.getExtra() != null) } String describeJar(JarFile jar) { return describeEntry(jar, "com/sun/jna/openbsd-x86-64/libjnidispatch.so", 1671223758L) + '\n'\ + describeEntry(jar, "com/sun/jna/linux-loongarch64/libjnidispatch.so", 1671223358L) } String describe(String name) { def file = new File(basedir, "target/" + name) def jar = new JarFile(file) println(name) return "sha1 = " + MessageDigest.getInstance("SHA1").digest(file.bytes).encodeHex().toString()\ + "\n" + describeJar(jar) } void describeTz(TimeZone tz) { println("TZ = " + tz.getID() + ", raw offset = " + tz.getRawOffset() / 60000 + " min., offset to current TZ = " + (tz.getRawOffset() - TimeZone.getDefault().getRawOffset()) / 60000 + " min.") } describeTz(TimeZone.getDefault()) println(describe("dependency/jna-5.13.0.jar")) println(describe("current-OS.jar")) def utcDescription = describe("UTC.jar") describeTz(TimeZone.getTimeZone("Etc/UTC")) println(utcDescription) def tokyoDescription = describe("Tokyo.jar") describeTz(TimeZone.getTimeZone("Asia/Tokyo")) println(tokyoDescription) describeTz(TimeZone.getTimeZone("Canada/Yukon")) println(describe("Yukon.jar")) assert utcDescription == tokyoDescription ================================================ FILE: src/it/projects/MSHADE-420/zipdetails.txt ================================================ # 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. # extract of zipdetails tool (https://perldoc.perl.org/zipdetails) output on target/dependency/jna-5.13.0.jar # and on UTC.jar and Tokyo.jar # to compare details of a problematic zip entry vs non-problematic in origin jar # vs in shaded jars # # extracts from *.zipdetails.txt and *.zipdetails-stderr.txt files generated by: $ for n in UTC Tokyo dependency/jna-5.13.0 ; do sha1sum $n.jar ; zipdetails $n.jar > $n-zipdetails.txt 2> $n-zipdetails-stderr.txt ; done 2f9bd2808b7f93058abd8a66e160b699e2ff53f1 UTC.jar bc0b043cbcdda98b53d9aa8f8ef3a4e7f6624708 Tokyo.jar 1200e7ebeedbe0d10062093f32925a912020e747 dependency/jna-5.13.0.jar # done on my own Linux box with Paris TZ in January 2024 (I don't know if other OS TZ may have an impact, or daylight savings, # recording details for comparing with anybody getting different results on SHA1s) # focused on problematic zip entries com/sun/jna/openbsd-x86-64/libjnidispatch.so vs non-problematic com/sun/jna/linux-loongarch64/libjnidispatch.so # initial zipdetails contains 2 "Extra ID" fields ## ## jna-5.13.0.jar ## # zip entry in jna-5.13.0.jar causing the issue ADD 1600309 1648805 CENTRAL HEADER ref Local #B5: com/sun/jna/openbsd-x86-64/libjnidispatch.so 1CAAA1 CENTRAL HEADER #B5 02014B50 1CAAA5 Created Zip Spec 14 '2.0' 1CAAA6 Created OS 03 'Unix' 1CAAA7 Extract Zip Spec 0A '1.0' 1CAAA8 Extract OS 00 'MS-DOS' 1CAAA9 General Purpose Flag 0800 [Bits 1-2] 0 'Normal Compression' [Bit 11] 1 'Language Encoding' 1CAAAB Compression Method 0008 'Deflated' 1CAAAD Last Mod Time 5590AE29 'Fri Dec 16 21:49:18 2022' 1CAAB1 CRC 9D24CF73 1CAAB5 Compressed Length 0000BD70 1CAAB9 Uncompressed Length 0001E03E 1CAABD Filename Length 002C 1CAABF Extra Length 0018 1CAAC1 Comment Length 0000 1CAAC3 Disk Start 0000 1CAAC5 Int File Attributes 0000 [Bit 0] 0 'Binary Data' 1CAAC7 Ext File Attributes 81ED0000 1CAACB Local Header Offset 00186B35 1CAACF Filename 'com/sun/jna/openbsd-x86- 64/libjnidispatch.so' 1CAAFB Extra ID #0001 5455 'UT: Extended Timestamp' 1CAAFD Length 0005 1CAAFF Flags '03 mod access' 1CAB00 Mod Time 639CD9CE 'Fri Dec 16 21:49:18 2022' 1CAB04 Extra ID #0002 7875 'ux: Unix Extra Type 3' 1CAB06 Length 000B 1CAB08 Version 01 1CAB09 UID Size 04 1CAB0A UID 00000000 1CAB0E GID Size 04 1CAB0F GID 00000000 # usual zip entry jna-5.13.0.jar, not causing any issue ADD 1059307 1109553 CENTRAL HEADER ref Local #A1: com/sun/jna/linux-loongarch64/libjnidispatch.so 1CA392 CENTRAL HEADER #A1 02014B50 1CA396 Created Zip Spec 14 '2.0' 1CA397 Created OS 03 'Unix' 1CA398 Extract Zip Spec 0A '1.0' 1CA399 Extract OS 00 'MS-DOS' 1CA39A General Purpose Flag 0800 [Bits 1-2] 0 'Normal Compression' [Bit 11] 1 'Language Encoding' 1CA39C Compression Method 0008 'Deflated' 1CA39E Last Mod Time 5590AD53 'Fri Dec 16 21:42:38 2022' 1CA3A2 CRC 1AA0D033 1CA3A6 Compressed Length 0000C446 1CA3AA Uncompressed Length 0005B768 1CA3AE Filename Length 002F 1CA3B0 Extra Length 0000 1CA3B2 Comment Length 0000 1CA3B4 Disk Start 0000 1CA3B6 Int File Attributes 0000 [Bit 0] 0 'Binary Data' 1CA3B8 Ext File Attributes 81A40000 1CA3BC Local Header Offset 001029EB 1CA3C0 Filename 'com/sun/jna/linux- loongarch64/libjnidispatch.so' ## ## UTC.jar = shaded content with JVM UTC TZ ## # zip entry in UTC.jar having an issue ADD 1317115 1365611 CENTRAL HEADER ref Local #38: com/sun/jna/openbsd-x86-64/libjnidispatch.so 14E7BF CENTRAL HEADER #38 02014B50 14E7C3 Created Zip Spec 14 '2.0' 14E7C4 Created OS 00 'MS-DOS' 14E7C5 Extract Zip Spec 14 '2.0' 14E7C6 Extract OS 00 'MS-DOS' 14E7C7 General Purpose Flag 0808 [Bits 1-2] 0 'Normal Compression' [Bit 3] 1 'Streamed' [Bit 11] 1 'Language Encoding' 14E7C9 Compression Method 0008 'Deflated' 14E7CB Last Mod Time 5590A629 'Fri Dec 16 20:49:18 2022' 14E7CF CRC 9D24CF73 14E7D3 Compressed Length 0000BD70 14E7D7 Uncompressed Length 0001E03E 14E7DB Filename Length 002C 14E7DD Extra Length 0000 14E7DF Comment Length 0000 14E7E1 Disk Start 0000 14E7E3 Int File Attributes 0000 [Bit 0] 0 'Binary Data' 14E7E5 Ext File Attributes 00000000 14E7E9 Local Header Offset 001418FB 14E7ED Filename 'com/sun/jna/openbsd-x86- 64/libjnidispatch.so' # zip entry in UTC.jar not having an issue ADD 776025 826271 CENTRAL HEADER ref Local #24: com/sun/jna/linux-loongarch64/libjnidispatch.so 14E188 CENTRAL HEADER #24 02014B50 14E18C Created Zip Spec 14 '2.0' 14E18D Created OS 00 'MS-DOS' 14E18E Extract Zip Spec 14 '2.0' 14E18F Extract OS 00 'MS-DOS' 14E190 General Purpose Flag 0808 [Bits 1-2] 0 'Normal Compression' [Bit 3] 1 'Streamed' [Bit 11] 1 'Language Encoding' 14E192 Compression Method 0008 'Deflated' 14E194 Last Mod Time 5590AD53 'Fri Dec 16 21:42:38 2022' 14E198 CRC 1AA0D033 14E19C Compressed Length 0000C446 14E1A0 Uncompressed Length 0005B768 14E1A4 Filename Length 002F 14E1A6 Extra Length 0000 14E1A8 Comment Length 0000 14E1AA Disk Start 0000 14E1AC Int File Attributes 0000 [Bit 0] 0 'Binary Data' 14E1AE Ext File Attributes 00000000 14E1B2 Local Header Offset 000BD759 14E1B6 Filename 'com/sun/jna/linux- loongarch64/libjnidispatch.so' ## ## Tokyo.jar = shaded content with JVM Asia/Tokyo TZ ## # zip entry in Tokyo.jar having an issue ADD 1317115 1365611 CENTRAL HEADER ref Local #38: com/sun/jna/openbsd-x86-64/libjnidispatch.so 14E7BF CENTRAL HEADER #38 02014B50 14E7C3 Created Zip Spec 14 '2.0' 14E7C4 Created OS 00 'MS-DOS' 14E7C5 Extract Zip Spec 14 '2.0' 14E7C6 Extract OS 00 'MS-DOS' 14E7C7 General Purpose Flag 0808 [Bits 1-2] 0 'Normal Compression' [Bit 3] 1 'Streamed' [Bit 11] 1 'Language Encoding' 14E7C9 Compression Method 0008 'Deflated' 14E7CB Last Mod Time 55912E29 'Sat Dec 17 05:49:18 2022' 14E7CF CRC 9D24CF73 14E7D3 Compressed Length 0000BD70 14E7D7 Uncompressed Length 0001E03E 14E7DB Filename Length 002C 14E7DD Extra Length 0000 14E7DF Comment Length 0000 14E7E1 Disk Start 0000 14E7E3 Int File Attributes 0000 [Bit 0] 0 'Binary Data' 14E7E5 Ext File Attributes 00000000 14E7E9 Local Header Offset 001418FB 14E7ED Filename 'com/sun/jna/openbsd-x86- 64/libjnidispatch.so' # zip entry in Tokyo.jar not having an issue ADD 776025 826271 CENTRAL HEADER ref Local #24: com/sun/jna/linux-loongarch64/libjnidispatch.so 14E188 CENTRAL HEADER #24 02014B50 14E18C Created Zip Spec 14 '2.0' 14E18D Created OS 00 'MS-DOS' 14E18E Extract Zip Spec 14 '2.0' 14E18F Extract OS 00 'MS-DOS' 14E190 General Purpose Flag 0808 [Bits 1-2] 0 'Normal Compression' [Bit 3] 1 'Streamed' [Bit 11] 1 'Language Encoding' 14E192 Compression Method 0008 'Deflated' 14E194 Last Mod Time 5590AD53 'Fri Dec 16 21:42:38 2022' 14E198 CRC 1AA0D033 14E19C Compressed Length 0000C446 14E1A0 Uncompressed Length 0005B768 14E1A4 Filename Length 002F 14E1A6 Extra Length 0000 14E1A8 Comment Length 0000 14E1AA Disk Start 0000 14E1AC Int File Attributes 0000 [Bit 0] 0 'Binary Data' 14E1AE Ext File Attributes 00000000 14E1B2 Local Header Offset 000BD759 14E1B6 Filename 'com/sun/jna/linux- loongarch64/libjnidispatch.so' ================================================ FILE: src/it/projects/MSHADE-462/all/pom.xml ================================================ org.apache.maven.its.shade.sa mshade-462 1.0-SNAPSHOT ../pom.xml 4.0.0 all jar org.apache.maven.its.shade.sa one ${project.version} compile true org.apache.maven.plugins maven-shade-plugin @project.version@ package shade true false false org.apache.maven.its.shade.sa:one ================================================ FILE: src/it/projects/MSHADE-462/invoker.properties ================================================ # 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.timeoutInSeconds=60 invoker.goals = clean install ================================================ FILE: src/it/projects/MSHADE-462/one/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.sa mshade-462 1.0-SNAPSHOT one jar ================================================ FILE: src/it/projects/MSHADE-462/one/src/main/java/org/apache/one/One.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.one; public class One { } ================================================ FILE: src/it/projects/MSHADE-462/pom.xml ================================================ org.apache apache 31 4.0.0 org.apache.maven.its.shade.sa mshade-462 1.0-SNAPSHOT pom UTF-8 org.apache.maven.its.shade.sa one ${project.version} one all org.apache.maven.plugins maven-compiler-plugin @version.maven-compiler-plugin@ -proc:none -parameters true 1.8 1.8 UTF-8 ================================================ FILE: src/it/projects/MSHADE-467_parallel-dependency-reduced-pom/invoker.properties ================================================ # 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.goals = package -T 4 ================================================ FILE: src/it/projects/MSHADE-467_parallel-dependency-reduced-pom/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.parallel MSHADE-467 1.0.0-SNAPSHOT pom shadeMT1 shadeMT2 shadeMT3 shadeMT4 org.apache.commons commons-vfs2 2.9.0 commons-logging commons-logging org.apache.hadoop * com.vividsolutions jts 1.13 xercesImpl xerces com.itextpdf itextpdf 5.5.13.3 * * org.apache.xmlgraphics batik-swing 1.17 xml-apis xml-apis org.apache.xmlgraphics batik-ext org.apache.xmlgraphics batik-dom 1.17 xerces xercesImpl org.apache.xmlgraphics batik-transcoder 1.17 * org.apache.avalon org.apache.xmlgraphics fop org.springframework.boot spring-boot-starter-test 2.7.18 test org.junit.jupiter junit-jupiter io.grpc grpc-core 1.58.0 io.micrometer micrometer-registry-stackdriver 1.9.16 javax.annotation javax.annotation-api org.springframework.boot spring-boot 2.7.18 org.slf4j slf4j-simple 1.7.36 org.apache.maven.plugins maven-shade-plugin @project.version@ package shade org.springframework.boot:* true ================================================ FILE: src/it/projects/MSHADE-467_parallel-dependency-reduced-pom/shadeMT1/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.parallel MSHADE-467 1.0.0-SNAPSHOT shadeMT1 maven-shade-plugin ================================================ FILE: src/it/projects/MSHADE-467_parallel-dependency-reduced-pom/shadeMT2/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.parallel MSHADE-467 1.0.0-SNAPSHOT shadeMT2 maven-shade-plugin ================================================ FILE: src/it/projects/MSHADE-467_parallel-dependency-reduced-pom/shadeMT3/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.parallel MSHADE-467 1.0.0-SNAPSHOT shadeMT3 maven-shade-plugin ================================================ FILE: src/it/projects/MSHADE-467_parallel-dependency-reduced-pom/shadeMT4/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.parallel MSHADE-467 1.0.0-SNAPSHOT shadeMT4 maven-shade-plugin ================================================ FILE: src/it/projects/MSHADE-467_parallel-dependency-reduced-pom/verify.groovy ================================================ /* * 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. */ (1..4).each { def exclusionCount = new File("$basedir/shadeMT$it/dependency-reduced-pom.xml") .readLines() .findAll { it.contains '' } .size() assert exclusionCount == 5 } || true ================================================ FILE: src/it/projects/artifact-includes-excludes/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.aie test 1.0 MSHADE-33 Test artifact selection via glob includes/excludes. junit junit 3.8.2 org.apache.maven.its.shade.aie a 0.1 org.apache.maven.its.shade.aie b 0.2 org.apache.maven.plugins maven-shade-plugin @project.version@ attach-shade shade false org.apache.maven.its.shade.aie *:b:jar: ================================================ FILE: src/it/projects/artifact-includes-excludes/verify.bsh ================================================ /* * 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.io.*; import java.util.jar.*; String[] wanted = { "a.properties", }; String[] unwanted = { "b.properties", "junit/framework/TestCase.class", }; JarFile jarFile = new JarFile( new File( basedir, "target/test-1.0.jar" ) ); for ( String path : wanted ) { if ( jarFile.getEntry( path ) == null ) { throw new IllegalStateException( "wanted path is missing: " + path ); } } for ( String path : unwanted ) { if ( jarFile.getEntry( path ) != null ) { throw new IllegalStateException( "unwanted path is present: " + path ); } } jarFile.close(); ================================================ FILE: src/it/projects/attach-after-lifecycle-fork/invoker.properties ================================================ # 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. # verify -shade and -sources are attached and installed invoker.goals = install ================================================ FILE: src/it/projects/attach-after-lifecycle-fork/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.aalf test 1.0 jar MSHADE-44 Test that attaching artifacts works when the plugin is executed after another plugin that forked the lifecycle. org.apache.maven.plugins maven-compiler-plugin @version.maven-compiler-plugin@ org.apache.maven.plugins maven-install-plugin @version.maven-install-plugin@ org.apache.maven.plugins maven-jar-plugin @version.maven-jar-plugin@ org.apache.maven.plugins maven-resources-plugin @version.maven-resources-plugin@ org.apache.maven.plugins maven-source-plugin 2.0.4 attach-sources package jar org.apache.maven.plugins maven-shade-plugin @project.version@ attach-shade package shade true shade false org.apache.maven.plugins maven-surefire-plugin @version.maven-surefire@ ================================================ FILE: src/it/projects/attach-after-lifecycle-fork/setup.bsh ================================================ /* * 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.io.*; import java.util.*; import org.codehaus.plexus.util.*; File file = new File( localRepositoryPath, "org/apache/maven/its/shade/aalf" ); System.out.println( "Deleting " + file ); FileUtils.deleteDirectory( file ); return true; ================================================ FILE: src/it/projects/attach-after-lifecycle-fork/verify.bsh ================================================ /* * 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.io.*; import java.util.*; String[] paths = { "org/apache/maven/its/shade/aalf/test/1.0/test-1.0-shade.jar", "org/apache/maven/its/shade/aalf/test/1.0/test-1.0-sources.jar", }; for ( String path : paths ) { File file = new File( localRepositoryPath, path ); System.out.println( "Checking for existence of " + file ); if ( !file.isFile() ) { throw new FileNotFoundException( "Missing: " + file.getAbsolutePath() ); } } return true; ================================================ FILE: src/it/projects/attached-artifact-type/consumer/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.aat parent 1.0 consumer ear MSHADE-46 :: Shaded Artifact Consumer Test that attached shaded artifacts have the same type as the original main artifact. org.apache.maven.its.shade.aat shade 1.0 ejb shaded org.apache.maven.plugins maven-ear-plugin org.apache.maven.its.shade.aat shade shaded ================================================ FILE: src/it/projects/attached-artifact-type/invoker.properties ================================================ # 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. # NOTE: Running only up to "package" is crucial, we want to check proper resolution from the reactor invoker.goals = clean package ================================================ FILE: src/it/projects/attached-artifact-type/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.aat parent 1.0 pom MSHADE-46 Test that attached shaded artifacts have the same type as the original main artifact. shade consumer true org.apache.maven.plugins maven-compiler-plugin @version.maven-compiler-plugin@ org.apache.maven.plugins maven-install-plugin @version.maven-install-plugin@ org.apache.maven.plugins maven-ear-plugin 2.3.1 org.apache.maven.plugins maven-ejb-plugin 2.1 org.apache.maven.plugins maven-resources-plugin @version.maven-resources-plugin@ org.apache.maven.plugins maven-shade-plugin @project.version@ org.apache.maven.plugins maven-surefire-plugin @version.maven-surefire@ ================================================ FILE: src/it/projects/attached-artifact-type/shade/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.aat parent 1.0 shade ejb MSHADE-46 :: Shaded Artifact Producer Test that attached shaded artifacts have the same type as the original main artifact. org.apache.maven.plugins maven-shade-plugin attach-shaded-artifact package shade true shaded false ================================================ FILE: src/it/projects/attached-artifact-type/shade/src/main/resources/META-INF/ejb-jar.xml ================================================ ================================================ FILE: src/it/projects/component-descriptor-relocation/app/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.cdr mshade71 1.0 test org.apache.maven.its.shade.cdr comp 0.1 org.codehaus.plexus plexus-container-default 1.0-alpha-9-stable-1 junit junit org.apache.maven.plugins maven-shade-plugin @project.version@ shade shade false org.apache.maven.component.api hidden.api org.apache.maven.component.impl hidden.impl org.apache.maven.test hidden.impl org.codehaus.mojo exec-maven-plugin 1.1.1 run verify exec ${JAVA_HOME}/bin/java -classpath ${project.build.directory}/test-1.0.jar Main ================================================ FILE: src/it/projects/component-descriptor-relocation/app/src/main/java/Main.java ================================================ /* * 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 org.apache.maven.component.api.*; import org.codehaus.plexus.*; public class Main { public static void main( String[] args ) throws Exception { DefaultPlexusContainer container = new DefaultPlexusContainer(); container.initialize(); container.start(); Component comp = (Component) container.lookup( Component.class.getName(), "test" ); System.out.println( comp.getId() ); if ( !"test-default".equals( comp.getId() ) ) { throw new IllegalStateException( "bad component " + comp ); } } } ================================================ FILE: src/it/projects/component-descriptor-relocation/app/src/main/java/org/apache/maven/test/TestComponent.java ================================================ package org.apache.maven.test; /* * 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 org.apache.maven.component.api.*; public class TestComponent implements Component { private Component component; public String getId() { return "test-" + component.getId(); } } ================================================ FILE: src/it/projects/component-descriptor-relocation/app/src/main/resources/META-INF/plexus/components.xml ================================================ org.apache.maven.component.api.Component test org.apache.maven.test.TestComponent per-lookup org.apache.maven.component.api.Component default component ================================================ FILE: src/it/projects/component-descriptor-relocation/lib/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.cdr mshade71 1.0 org.apache.maven.its.shade.cdr comp 0.1 ================================================ FILE: src/it/projects/component-descriptor-relocation/lib/src/main/java/org/apache/maven/component/api/Component.java ================================================ package org.apache.maven.component.api; /* * 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 interface Component { String getId(); } ================================================ FILE: src/it/projects/component-descriptor-relocation/lib/src/main/java/org/apache/maven/component/impl/DefaultComponent.java ================================================ package org.apache.maven.component.impl; /* * 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 org.apache.maven.component.api.*; public class DefaultComponent implements Component { public String getId() { return "default"; } } ================================================ FILE: src/it/projects/component-descriptor-relocation/lib/src/main/resources/META-INF/plexus/components.xml ================================================ org.apache.maven.component.api.Component default org.apache.maven.component.impl.DefaultComponent per-lookup ================================================ FILE: src/it/projects/component-descriptor-relocation/pom.xml ================================================ 4.0.0 org.apache.maven.plugins.shade.its shade-parent 1.0 ../setup-parent org.apache.maven.its.shade.cdr mshade71 1.0 pom MSHADE-71 Test that Plexus component descriptors get adjusted to account for relocation of role/impl classes. org.apache.maven.plugins maven-compiler-plugin @version.maven-compiler-plugin@ org.apache.maven.plugins maven-jar-plugin @version.maven-jar-plugin@ org.apache.maven.plugins maven-resources-plugin @version.maven-resources-plugin@ org.apache.maven.plugins maven-surefire-plugin @version.maven-surefire@ lib app ================================================ FILE: src/it/projects/dep-reduced-pom/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.drp test 1.0 MSHADE-53 Test that creation of the dependency reduced POM properly handles dependencies with classifiers. org.apache.maven.its.shade.drp a 0.1 org.apache.maven.its.shade.drp b 0.2 client org.apache.maven.its.shade.drp c 1 pom org.apache.maven.plugins maven-shade-plugin @project.version@ attach-shade shade true false true target/dependency-reduced-pom.xml ================================================ FILE: src/it/projects/dep-reduced-pom/verify.groovy ================================================ /* * 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 groovy.xml.XmlParser File pomFile = new File( basedir, "target/dependency-reduced-pom.xml" ); assert pomFile.isFile() def ns = new groovy.xml.Namespace("http://maven.apache.org/POM/4.0.0") def pom = new XmlParser().parse( pomFile ) assert pom[ns.modelVersion].size() == 1 assert pom[ns.dependencies][ns.dependency].size() == 0 ================================================ FILE: src/it/projects/dep-reduced-pom-artifactset-provided-excludes/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.drpape test 1.0 MSHADE-311 Tests that creation of the dependency reduced POM does not create excludes for a provided transitive dependency. This dependency 'c' is a compile dependency of 'b' which is a provided dependency of this project. Shade-plugin is configured to only include (compile) dependency 'a', not 'b' (which must therefore be retained). Additionally (to prevent regressions), this project has a provided dependency 'd' which depends on 'e', but 'e' is excluded. That exclusion must be retained in the dependency reduced POM. org.apache.maven.its.shade.drpape a 0.1 org.apache.maven.its.shade.drpape b 0.1 provided org.apache.maven.its.shade.drpape d 0.1 provided org.apache.maven.its.shade.drpape e org.apache.maven.plugins maven-shade-plugin @project.version@ attach-shade shade true target/dependency-reduced-pom.xml org.apache.maven.its.shade.drpape:a ================================================ FILE: src/it/projects/dep-reduced-pom-artifactset-provided-excludes/verify.groovy ================================================ /* * 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 groovy.xml.XmlParser File pomFile = new File( basedir, "target/dependency-reduced-pom.xml" ); assert pomFile.isFile() def ns = new groovy.xml.Namespace("http://maven.apache.org/POM/4.0.0") def pom = new XmlParser().parse( pomFile ) assert pom[ns.modelVersion].size() == 1 assert pom[ns.dependencies][ns.dependency].size() == 2 def depB = pom[ns.dependencies][ns.dependency][0] assert depB[ns.artifactId].text().equals('b') assert depB[ns.scope].text().equals('provided') assert depB[ns.exclusions][ns.exclusion].size() == 0 def depD = pom[ns.dependencies][ns.dependency][1] assert depD[ns.artifactId].text().equals('d') assert depD[ns.scope].text().equals('provided') def depDExclusions = depD[ns.exclusions][ns.exclusion] assert depDExclusions.size() == 1 assert depDExclusions[0][ns.artifactId].text().equals('e') ================================================ FILE: src/it/projects/dep-reduced-pom-exclusions/invoker.properties ================================================ # 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.timeoutInSeconds=60 ================================================ FILE: src/it/projects/dep-reduced-pom-exclusions/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.drpe test 1.0 MSHADE-223 Test that creation of the dependency reduced POM properly handles dependencies with classifiers. org.apache.maven.its.shade.drpe a 0.1 org.apache.maven.its.shade.drpe c org.apache.maven.plugins maven-shade-plugin @project.version@ attach-shade shade true false true org.apache.maven.its.shade.drpe:a ================================================ FILE: src/it/projects/dep-reduced-pom-exclusions/verify.groovy ================================================ /* * 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 groovy.xml.XmlParser File pomFile = new File( basedir, "dependency-reduced-pom.xml" ) assert pomFile.isFile() def ns = new groovy.xml.Namespace("http://maven.apache.org/POM/4.0.0") def pom = new XmlParser().parse( pomFile ) assert pom[ns.modelVersion].size() == 1 assert pom[ns.dependencies][ns.dependency].size() == 2 assert pom[ns.dependencies][ns.dependency][0][ns.exclusions][ns.exclusion].size() == 1 assert pom[ns.dependencies][ns.dependency][1][ns.exclusions][ns.exclusion].size() == 1 ================================================ FILE: src/it/projects/dep-reduced-pom-relocated-result/child/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.drpwlp parent 1.0 child 1.0 jar MSHADE-66 Test that creation of the dependency reduced POM succeeds if the POM inherits from a parent that is only locally available. In other words, the parent can only be resolved by following the relativePath in the POM which demands for the dependency reduced POM to reside in the original project directory. junit junit 3.8.2 org.apache.maven.plugins maven-shade-plugin attach-shade package shade false true target/drp.xml ================================================ FILE: src/it/projects/dep-reduced-pom-relocated-result/invoker.properties ================================================ # 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.goals = clean package invoker.project = child ================================================ FILE: src/it/projects/dep-reduced-pom-relocated-result/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.drpwlp parent 1.0 pom MSHADE-66 Test that creation of the dependency reduced POM succeeds if the POM inherits from a parent that is only locally available. In other words, the parent can only be resolved by following the relativePath in the POM which demands for the dependency reduced POM to reside in the original project directory. child org.apache.maven.plugins maven-compiler-plugin @version.maven-compiler-plugin@ org.apache.maven.plugins maven-install-plugin @version.maven-install-plugin@ org.apache.maven.plugins maven-jar-plugin @version.maven-jar-plugin@ org.apache.maven.plugins maven-resources-plugin @version.maven-resources-plugin@ org.apache.maven.plugins maven-shade-plugin @project.version@ org.apache.maven.plugins maven-surefire-plugin @version.maven-surefire@ ================================================ FILE: src/it/projects/dep-reduced-pom-unique/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.drp test 1.0 MSHADE-53 Test that creation of the dependency reduced POM properly handles dependencies with classifiers. org.apache.maven.its.shade.drp a 0.1 org.apache.maven.its.shade.drp b 0.2 client org.apache.maven.its.shade.drp c 1 pom org.apache.maven.plugins maven-shade-plugin @project.version@ shade shade true false true true org.codehaus.mojo properties-maven-plugin 1.3.0 write-project-properties package target/project.properties ================================================ FILE: src/it/projects/dep-reduced-pom-unique/verify.groovy ================================================ /* * 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.io.*; import java.util.Properties; import groovy.xml.XmlParser def drps = basedir.listFiles( { dir, file -> file ==~ "dependency-reduced-.*\\.xml" } as FilenameFilter ) File pomFile = drps[0] def ns = new groovy.xml.Namespace("http://maven.apache.org/POM/4.0.0") def pom = new XmlParser().parse( pomFile ) assert pom[ns.modelVersion].size() == 1 assert pom[ns.dependencies][ns.dependency].size() == 0 def props = new File( basedir, "target/project.properties" ) Properties properties = new Properties(); FileInputStream inp = new FileInputStream( props ); properties.load( inp ); inp.close(); assert properties["maven.shade.dependency-reduced-pom"] != null ================================================ FILE: src/it/projects/dep-reduced-pom-use-base-version/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.drp test 1.0-SNAPSHOT MSHADE-136 Test that creation of the dependency reduced POM properly handles snapshot dependencies with useBaseVersion. org.apache.maven.its.shade.drp a 0.1-SNAPSHOT compile org.apache.maven.plugins maven-shade-plugin @project.version@ attach-shade shade true true true target/dependency-reduced-pom.xml ================================================ FILE: src/it/projects/dep-reduced-pom-use-base-version/verify.groovy ================================================ /* * 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 groovy.xml.XmlParser File pomFile = new File( basedir, "target/dependency-reduced-pom.xml" ); assert pomFile.isFile() def ns = new groovy.xml.Namespace("http://maven.apache.org/POM/4.0.0") def pom = new XmlParser().parse( pomFile ) assert pom[ns.modelVersion].size() == 1 assert pom[ns.dependencies][ns.dependency].size() == 1 // assert the dependency is named -SNAPSHOT and not -20130115.024354-82 assert pom[ns.dependencies][ns.dependency][0][ns.version][0].text().equals("0.1-SNAPSHOT") ================================================ FILE: src/it/projects/dep-reduced-pom-with-local-parent/child/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.drpwlp parent 1.0 child 1.0 jar MSHADE-66 Test that creation of the dependency reduced POM succeeds if the POM inherits from a parent that is only locally available. In other words, the parent can only be resolved by following the relativePath in the POM which demands for the dependency reduced POM to reside in the original project directory. junit junit 3.8.2 org.apache.maven.plugins maven-shade-plugin attach-shade package shade false true ================================================ FILE: src/it/projects/dep-reduced-pom-with-local-parent/invoker.properties ================================================ # 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.goals = clean package invoker.project = child ================================================ FILE: src/it/projects/dep-reduced-pom-with-local-parent/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.drpwlp parent 1.0 pom MSHADE-66 Test that creation of the dependency reduced POM succeeds if the POM inherits from a parent that is only locally available. In other words, the parent can only be resolved by following the relativePath in the POM which demands for the dependency reduced POM to reside in the original project directory. child org.apache.maven.plugins maven-compiler-plugin @version.maven-compiler-plugin@ org.apache.maven.plugins maven-install-plugin @version.maven-install-plugin@ org.apache.maven.plugins maven-jar-plugin @version.maven-jar-plugin@ org.apache.maven.plugins maven-resources-plugin @version.maven-resources-plugin@ org.apache.maven.plugins maven-shade-plugin @project.version@ org.apache.maven.plugins maven-surefire-plugin @version.maven-surefire@ ================================================ FILE: src/it/projects/duplicate-classes-with-reloc/app/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.dcwr test 1.0 MSHADE-30 Test that duplicate classes/resources on the class path are gracefully handled. org.apache.maven.its.shade.dcwr a 0.1 org.apache.maven.its.shade.dcwr b 0.1 org.apache.maven.plugins maven-compiler-plugin @version.maven-compiler-plugin@ org.apache.maven.plugins maven-jar-plugin @version.maven-jar-plugin@ org.apache.maven.plugins maven-resources-plugin @version.maven-resources-plugin@ org.apache.maven.plugins maven-shade-plugin @project.version@ shade package shade false org.apache hidden org.apache.maven.plugins maven-surefire-plugin @version.maven-surefire@ ================================================ FILE: src/it/projects/duplicate-classes-with-reloc/libs/a-0.1.pom ================================================ 4.0.0 org.apache.maven.its.shade.dcwr a 0.1 jar ================================================ FILE: src/it/projects/duplicate-classes-with-reloc/libs/b-0.1.pom ================================================ 4.0.0 org.apache.maven.its.shade.dcwr b 0.1 jar ================================================ FILE: src/it/projects/duplicate-classes-with-reloc/libs/src/main/java/org/apache/maven/its/shade/MyInterface.java ================================================ package org.apache.maven.its.shade; /* * 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 interface MyInterface { void execute(); } ================================================ FILE: src/it/projects/duplicate-classes-with-reloc/libs/src/main/java/org/apache/maven/its/shade/impl/MyImpl.java ================================================ package org.apache.maven.its.shade.impl; /* * 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 org.apache.maven.its.shade.MyInterface; public class MyImpl implements MyInterface { @Override public void execute() { // do nothing } } ================================================ FILE: src/it/projects/duplicate-classes-with-reloc/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.dcwr mshade30 1.0 pom MSHADE-30 Test that duplicate classes/resources on the class path are gracefully handled. libs/a-0.1.pom libs/b-0.1.pom app ================================================ FILE: src/it/projects/duplicate-classes-without-reloc/app/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.dcwor test 1.0 org.apache.maven.its.shade.dcwor a 0.1 org.apache.maven.its.shade.dcwor b 0.1 org.apache.maven.plugins maven-compiler-plugin @version.maven-compiler-plugin@ org.apache.maven.plugins maven-jar-plugin @version.maven-jar-plugin@ org.apache.maven.plugins maven-resources-plugin @version.maven-resources-plugin@ org.apache.maven.plugins maven-shade-plugin @project.version@ shade shade false org.apache.maven.plugins maven-surefire-plugin @version.maven-surefire@ ================================================ FILE: src/it/projects/duplicate-classes-without-reloc/libs/a-0.1.pom ================================================ 4.0.0 org.apache.maven.its.shade.dcwor a 0.1 jar ================================================ FILE: src/it/projects/duplicate-classes-without-reloc/libs/b-0.1.pom ================================================ 4.0.0 org.apache.maven.its.shade.dcwor b 0.1 jar ================================================ FILE: src/it/projects/duplicate-classes-without-reloc/libs/src/main/java/org/apache/maven/its/shade/MyInterface.java ================================================ package org.apache.maven.its.shade; /* * 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 interface MyInterface { void execute(); } ================================================ FILE: src/it/projects/duplicate-classes-without-reloc/libs/src/main/java/org/apache/maven/its/shade/impl/MyImpl.java ================================================ package org.apache.maven.its.shade.impl; /* * 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 org.apache.maven.its.shade.MyInterface; public class MyImpl implements MyInterface { @Override public void execute() { // do nothing } } ================================================ FILE: src/it/projects/duplicate-classes-without-reloc/libs/src/main/resources/some-ordinary-resource.txt ================================================ # 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. ================================================ FILE: src/it/projects/duplicate-classes-without-reloc/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.dcwor mshade30 1.0 pom MSHADE-30 Test that duplicate classes/resources on the class path are gracefully handled. libs/a-0.1.pom libs/b-0.1.pom app ================================================ FILE: src/it/projects/empty-apache-notice-transform/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.eant empty-apache-notice-transform 0.1 jar MSHADE-101 Test that NullPointerException is not thrown when projectName parameter is unset. org.apache.velocity velocity 1.7 junit junit 3.8.1 test org.apache.maven.plugins maven-shade-plugin @project.version@ package shade ================================================ FILE: src/it/projects/empty-relocation-pattern/invoker.properties ================================================ # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. invoker.buildResult = failure ================================================ FILE: src/it/projects/empty-relocation-pattern/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.eant empty-relocation-pattern 0.1-SNAPSHOT jar Prevent usage of empty pattern Test that relocations with empty patterns lead to build failure (https://github.com/apache/maven-shade-plugin/issues/793). org.apache.maven.plugins maven-shade-plugin @project.version@ package shade org.example ================================================ FILE: src/it/projects/empty-relocation-shaded-pattern/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.eant empty-relocation-shaded-pattern 0.1-SNAPSHOT jar MSHADE-94 Test that NullPointerException is not thrown when shadedPattern parameter is unset. org.apache.maven.plugins maven-shade-plugin @project.version@ package shade org.example ================================================ FILE: src/it/projects/extrajar/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.extrajar test 1.0 jar extrajar Test that asserts addition of extra-jars. 1.7.36 org.slf4j slf4j-api ${slf4j.version} org.apache.maven.plugins maven-shade-plugin @project.version@ attach-shade package shade true org.slf4j:slf4j-simple:${slf4j.version} *:* META-INF/MANIFEST.MF ================================================ FILE: src/it/projects/extrajar/verify.bsh ================================================ /* * 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.io.*; import java.util.jar.*; String[] wanted = { "org/slf4j/Logger.class", "org/slf4j/impl/SimpleLogger.class" }; JarFile jarFile = new JarFile( new File( basedir, "target/test-1.0-shaded.jar" ) ); for ( String path : wanted ) { if ( jarFile.getEntry( path ) == null ) { throw new IllegalStateException( "wanted path is missing: " + path ); } } jarFile.close(); ================================================ FILE: src/it/projects/extrajar-missing-file/invoker.properties ================================================ # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. invoker.buildResult = failure ================================================ FILE: src/it/projects/extrajar-missing-file/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.extrajar test 1.0 jar extrajar Test that asserts failure if specified extra jar is not a file. 1.7.36 org.slf4j slf4j-api ${slf4j.version} org.apache.maven.plugins maven-shade-plugin @project.version@ attach-shade package shade true ${project.build.directory}/no-such-file.jar ================================================ FILE: src/it/projects/filter-artifact-contents/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.fac test 1.0 jar MSHADE-68 Test that artifact contents can be filtered using glob includes/excludes. org.apache.maven.its.shade.fac a 0.1 org.apache.maven.its.shade.fac b 0.1 client org.apache.maven.plugins maven-shade-plugin @project.version@ attach-shade package shade false org.apache.maven.its.shade.fac:a **/a.properties org.apache.maven.its.shade.fac:b:client org/apache/* org/apache/maven/b/ *:* org/* ================================================ FILE: src/it/projects/filter-artifact-contents/verify.bsh ================================================ /* * 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.io.*; import java.util.jar.*; String[] wanted = { "a.properties", "org/apache/a.properties", "org/apache/maven/a.properties", "b.properties", "org/apache/maven/b.properties", }; String[] unwanted = { "META-INF/maven/org.apache.maven.its.shade.fac/a/pom.properties", "org/a.properties", "org/b.properties", "org/apache/b.properties", "org/apache/maven/b/b.properties", }; JarFile jarFile = new JarFile( new File( basedir, "target/test-1.0.jar" ) ); for ( String path : wanted ) { if ( jarFile.getEntry( path ) == null ) { throw new IllegalStateException( "wanted path is missing: " + path ); } } for ( String path : unwanted ) { if ( jarFile.getEntry( path ) != null ) { throw new IllegalStateException( "unwanted path is present: " + path ); } } jarFile.close(); ================================================ FILE: src/it/projects/finalNameBuild/invoker.properties ================================================ # 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.goals = install ================================================ FILE: src/it/projects/finalNameBuild/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.fnb finalNameBuild 1.0 MSHADE-54 :: Shaded Artifact Producer Test that attached artifact has the correct finalName if the finalName is set in the build section and artifact attaching is NOT activated. MyFinalName org.apache.maven.plugins maven-shade-plugin @project.version@ create-shaded-artifact package shade shaded false ================================================ FILE: src/it/projects/finalNameBuild/setup.bsh ================================================ /* * 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.io.*; import java.util.*; import org.codehaus.plexus.util.*; File file = new File( localRepositoryPath, "org/apache/maven/its/shade/fnb" ); System.out.println( "Deleting " + file ); FileUtils.deleteDirectory( file ); return true; ================================================ FILE: src/it/projects/finalNameBuild/src/main/resources/META-INF/ejb-jar.xml ================================================ ================================================ FILE: src/it/projects/finalNameBuild/verify.bsh ================================================ /* * 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.io.*; import java.util.*; import java.util.regex.*; try { // check for primary artifact, which is actually the shaded one! File file = new File( basedir, "target/MyFinalName.jar" ); System.out.println( "file with finalName : " + file ); if ( !file.exists() ) { System.out.println( "file with finalName does not exist: " + file ); return false; } // check for original unshaded jar File original = new File( basedir, "target/original-MyFinalName.jar" ); System.out.println( "'orifinal' file with name : " + original ); if ( !original.exists() ) { System.out.println( "'original' file does not exist: " + original ); return false; } // check for the artifact in the repo. This is the shaded one! File rfile = new File( localRepositoryPath , "org/apache/maven/its/shade/fnb/finalNameBuild/1.0/finalNameBuild-1.0.jar" ); System.out.println( "Checking for existence in repo: " + rfile ); if ( !rfile.isFile() ) { throw new FileNotFoundException( "Missing: " + rfile.getAbsolutePath() ); } } catch( Throwable t ) { t.printStackTrace(); return false; } return true; ================================================ FILE: src/it/projects/finalNameBuild-attached/invoker.properties ================================================ # 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.goals = install ================================================ FILE: src/it/projects/finalNameBuild-attached/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.fnba finalNameBuildAttached 1.0 MSHADE-54 :: Shaded Artifact Producer Test that attached artifact has the correct finalName if the finalName is set in the build section and artifact attaching is activated. MyFinalName org.apache.maven.plugins maven-shade-plugin @project.version@ attach-shaded-artifact package shade true shaded false ================================================ FILE: src/it/projects/finalNameBuild-attached/setup.bsh ================================================ /* * 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.io.*; import java.util.*; import org.codehaus.plexus.util.*; File file = new File( localRepositoryPath, "org/apache/maven/its/shade/fnba" ); System.out.println( "Deleting " + file ); FileUtils.deleteDirectory( file ); return true; ================================================ FILE: src/it/projects/finalNameBuild-attached/src/main/resources/META-INF/ejb-jar.xml ================================================ ================================================ FILE: src/it/projects/finalNameBuild-attached/verify.bsh ================================================ /* * 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.io.*; import java.util.*; import java.util.regex.*; try { // check for primary artifact, which is the unshaded one! File file = new File( basedir, "target/MyFinalName.jar" ); System.out.println( "file with finalName : " + file ); if ( !file.exists() ) { System.out.println( "file with finalName does not exist: " + file ); return false; } // check for the shaded jar File shaded = new File( basedir, "target/finalNameBuildAttached-1.0-shaded.jar" ); System.out.println( "shaded file with name : " + shaded ); if ( !shaded.exists() ) { System.out.println( "shaded file does not exist: " + shaded ); return false; } // check for the artifact in the repo (unshaded) File rfile = new File( localRepositoryPath , "org/apache/maven/its/shade/fnba/finalNameBuildAttached/1.0/finalNameBuildAttached-1.0.jar" ); System.out.println( "Checking for existence in repo: " + rfile ); if ( !rfile.isFile() ) { throw new FileNotFoundException( "Missing: " + rfile.getAbsolutePath() ); } // check for the shaded artifact in the repo (shaded as attached artifact) File afile = new File( localRepositoryPath , "org/apache/maven/its/shade/fnba/finalNameBuildAttached/1.0/finalNameBuildAttached-1.0-shaded.jar" ); System.out.println( "Checking for existence in repo: " + afile ); if ( !afile.isFile() ) { throw new FileNotFoundException( "Missing: " + afile.getAbsolutePath() ); } } catch( Throwable t ) { t.printStackTrace(); return false; } return true; ================================================ FILE: src/it/projects/finalNameShade/invoker.properties ================================================ # 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.goals = install ================================================ FILE: src/it/projects/finalNameShade/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.fns finalNameShade 1.0 MSHADE-54 :: Shaded Artifact Producer Test that attached artifact has the correct finalName if the finalName is set in the shade plugin section and artifact attaching is NOT activated. org.apache.maven.plugins maven-shade-plugin @project.version@ attach-shaded-artifact package shade MyFinalShadeName shaded false ================================================ FILE: src/it/projects/finalNameShade/setup.bsh ================================================ /* * 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.io.*; import java.util.*; import org.codehaus.plexus.util.*; File file = new File( localRepositoryPath, "org/apache/maven/its/shade/fns" ); System.out.println( "Deleting " + file ); FileUtils.deleteDirectory( file ); return true; ================================================ FILE: src/it/projects/finalNameShade/src/main/resources/META-INF/ejb-jar.xml ================================================ ================================================ FILE: src/it/projects/finalNameShade/verify.bsh ================================================ /* * 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.io.*; import java.util.*; import java.util.regex.*; try { // check for primary artifact, which is the unshaded one! File file = new File( basedir, "target/finalNameShade-1.0.jar" ); System.out.println( "file with finalName : " + file ); if ( !file.exists() ) { System.out.println( "file with finalName does not exist: " + file ); return false; } // check for the shaded jar File shaded = new File( basedir, "target/MyFinalShadeName.jar" ); System.out.println( "shaded file with name : " + shaded ); if ( !shaded.exists() ) { System.out.println( "shaded file does not exist: " + shaded ); return false; } // check for the artifact in the repo File rfile = new File( localRepositoryPath , "org/apache/maven/its/shade/fns/finalNameShade/1.0/finalNameShade-1.0.jar" ); System.out.println( "Checking for existence in repo: " + rfile ); if ( !rfile.isFile() ) { throw new FileNotFoundException( "Missing: " + rfile.getAbsolutePath() ); } } catch( Throwable t ) { t.printStackTrace(); return false; } return true; ================================================ FILE: src/it/projects/finalNameShade-attached/invoker.properties ================================================ # 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.goals = install ================================================ FILE: src/it/projects/finalNameShade-attached/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.fnsa finalNameShadeAttached 1.0 MSHADE-54 :: Shaded Artifact Producer Test that attached artifact has the correct finalName if the finalName is set in the shade plugin section and artifact attaching is activated. org.apache.maven.plugins maven-shade-plugin @project.version@ attach-shaded-artifact package shade MyFinalShadeName true shaded false ================================================ FILE: src/it/projects/finalNameShade-attached/setup.bsh ================================================ /* * 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.io.*; import java.util.*; import org.codehaus.plexus.util.*; File file = new File( localRepositoryPath, "org/apache/maven/its/shade/fnsa" ); System.out.println( "Deleting " + file ); FileUtils.deleteDirectory( file ); return true; ================================================ FILE: src/it/projects/finalNameShade-attached/src/main/resources/META-INF/ejb-jar.xml ================================================ ================================================ FILE: src/it/projects/finalNameShade-attached/verify.bsh ================================================ /* * 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.io.*; import java.util.*; import java.util.regex.*; try { // check for primary artifact, which is the unshaded one! File file = new File( basedir, "target/finalNameShadeAttached-1.0.jar" ); System.out.println( "file with finalName : " + file ); if ( !file.exists() ) { System.out.println( "file with finalName does not exist: " + file ); return false; } // check for the shaded jar File shaded = new File( basedir, "target/MyFinalShadeName.jar" ); System.out.println( "shaded file with name : " + shaded ); if ( !shaded.exists() ) { System.out.println( "shaded file does not exist: " + shaded ); return false; } // check for the artifact in the repo File rfile = new File( localRepositoryPath , "org/apache/maven/its/shade/fnsa/finalNameShadeAttached/1.0/finalNameShadeAttached-1.0.jar" ); System.out.println( "Checking for existence in repo: " + rfile ); if ( !rfile.isFile() ) { throw new FileNotFoundException( "Missing: " + rfile.getAbsolutePath() ); } // check for the shaded artifact in the repo File afile = new File( localRepositoryPath , "org/apache/maven/its/shade/fnsa/finalNameShadeAttached/1.0/finalNameShadeAttached-1.0-shaded.jar" ); System.out.println( "Checking for existence in repo: " + afile ); if ( !afile.isFile() ) { throw new FileNotFoundException( "Missing: " + afile.getAbsolutePath() ); } } catch( Throwable t ) { t.printStackTrace(); return false; } return true; ================================================ FILE: src/it/projects/implicit-inclusion-of-project-artifact/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.iiopa test 1.0 jar MSHADE-72 Test that the project artifact is included in the output JAR even if it is not explicitly given by the non-empty includes for the artifact set. junit junit 3.8.2 org.apache.maven.plugins maven-shade-plugin @project.version@ attach-shade package shade false junit:junit ================================================ FILE: src/it/projects/implicit-inclusion-of-project-artifact/src/main/java/Passed.java ================================================ /* * 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 Passed { } ================================================ FILE: src/it/projects/implicit-inclusion-of-project-artifact/verify.bsh ================================================ /* * 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.io.*; import java.util.jar.*; String[] wanted = { "Passed.class", }; JarFile jarFile = new JarFile( new File( basedir, "target/test-1.0.jar" ) ); for ( String path : wanted ) { if ( jarFile.getEntry( path ) == null ) { throw new IllegalStateException( "wanted path is missing: " + path ); } } jarFile.close(); ================================================ FILE: src/it/projects/manifest-retained/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.mr test 1.0 jar MSHADE-20 Test that existing manifest entries are retained upon shading. org.apache.maven.plugins maven-shade-plugin @project.version@ org.apache.maven.plugins maven-compiler-plugin @version.maven-compiler-plugin@ org.apache.maven.plugins maven-install-plugin @version.maven-install-plugin@ org.apache.maven.plugins maven-jar-plugin @version.maven-jar-plugin@ org.apache.maven.Main PASSED org.apache.maven.plugins maven-resources-plugin @version.maven-resources-plugin@ org.apache.maven.plugins maven-shade-plugin @project.version@ attach-shade package shade true shaded org.apache.maven.plugins maven-surefire-plugin @version.maven-surefire@ ================================================ FILE: src/it/projects/manifest-retained/verify.bsh ================================================ /* * 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.io.*; import java.util.jar.*; JarFile jarFile = new JarFile( new File( basedir, "target/test-1.0-shaded.jar" ) ); Manifest mf = jarFile.getManifest(); jarFile.close(); if ( !"PASSED".equals( mf.getMainAttributes().getValue( "Test-Entry" ) ) ) { throw new IllegalStateException( "MANIFEST.MF is incomplete" ); } if ( !"org.apache.maven.Main".equals( mf.getMainAttributes().getValue( "Main-Class" ) ) ) { throw new IllegalStateException( "MANIFEST.MF is incomplete" ); } return true; ================================================ FILE: src/it/projects/manifest-transformed/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.mt test 1.0 jar MSHADE-77 Test that manifest is properly transformed and ends up as the first entry in the JAR. org.apache.maven.plugins maven-shade-plugin @project.version@ org.apache.maven.plugins maven-compiler-plugin @version.maven-compiler-plugin@ org.apache.maven.plugins maven-install-plugin @version.maven-install-plugin@ org.apache.maven.plugins maven-jar-plugin @version.maven-jar-plugin@ org.apache.maven.Main FAILED PASSED org.apache.maven.plugins maven-resources-plugin @version.maven-resources-plugin@ org.apache.maven.plugins maven-shade-plugin @project.version@ attach-shade package shade false org.apache.maven.Shade PASSED org.apache.maven.plugins maven-surefire-plugin @version.maven-surefire@ ================================================ FILE: src/it/projects/manifest-transformed/verify.bsh ================================================ /* * 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.io.*; import java.util.jar.*; // NOTE: We deliberately use JarInputStream and not JarFile here! JarInputStream jarStream = new JarInputStream( new FileInputStream( new File( basedir, "target/test-1.0.jar" ) ) ); Manifest mf = jarStream.getManifest(); jarStream.close(); if ( mf == null ) { throw new IllegalStateException( "META-INF/MANIFEST.MF is missing" ); } if ( !"PASSED".equals( mf.getMainAttributes().getValue( "Test-Entry" ) ) ) { throw new IllegalStateException( "META-INF/MANIFEST.MF is incomplete" ); } if ( !"PASSED".equals( mf.getMainAttributes().getValue( "Original-Entry" ) ) ) { throw new IllegalStateException( "META-INF/MANIFEST.MF is incomplete" ); } if ( !"org.apache.maven.Shade".equals( mf.getMainAttributes().getValue( "Main-Class" ) ) ) { throw new IllegalStateException( "META-INF/MANIFEST.MF is incomplete" ); } ================================================ FILE: src/it/projects/mini-jar/invoker.properties ================================================ # 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 = 1.8+ ================================================ FILE: src/it/projects/mini-jar/pom.xml ================================================ 4.0.0 org.apache.maven.plugins.shade.its shade-parent 1.0 ../setup-parent org.apache.maven.its.shade.mj test 1.0 jar MSHADE-84 Test that artifact contents can be filtered automatically to produce a mini jar that only contains the referenced classes. junit junit 3.8.2 org.apache.maven.plugins maven-compiler-plugin @version.maven-compiler-plugin@ org.apache.maven.plugins maven-shade-plugin @project.version@ attach-shade package shade false true ================================================ FILE: src/it/projects/mini-jar/src/main/java/Main.java ================================================ /* * 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 extends junit.framework.TestCase { } ================================================ FILE: src/it/projects/mini-jar/verify.bsh ================================================ /* * 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.io.*; import java.util.jar.*; String[] wanted = { "Main.class", "junit/framework/TestCase.class", "junit/swingui/icons/error.gif", }; String[] unwanted = { "junit/swingui/TestRunner.class", }; JarFile jarFile = new JarFile( new File( basedir, "target/test-1.0.jar" ) ); for ( String path : wanted ) { if ( jarFile.getEntry( path ) == null ) { throw new IllegalStateException( "wanted path is missing: " + path ); } } for ( String path : unwanted ) { if ( jarFile.getEntry( path ) != null ) { throw new IllegalStateException( "unwanted path is present: " + path ); } } jarFile.close(); ================================================ FILE: src/it/projects/mini-jar-jdk11+/invoker.properties ================================================ # 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 = 11+ ================================================ FILE: src/it/projects/mini-jar-jdk11+/pom.xml ================================================ 4.0.0 org.apache.maven.plugins.shade.its shade-parent 1.0 ../setup-parent org.apache.maven.its.shade.mj testmini 1.0 MSHADE-302 Test that artifact contents can be filtered automatically to produce a mini jar compiled with jdk11 that only contains the referenced classes. junit junit 3.8.2 maven-compiler-plugin @version.maven-compiler-plugin@ ${java.specification.version} org.apache.maven.plugins maven-shade-plugin @project.version@ attach-shade package shade false true org.apache.maven.plugins maven-invoker-plugin @version.maven-invoker-plugin@ ================================================ FILE: src/it/projects/mini-jar-jdk11+/src/main/java/Main.java ================================================ /* * 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 extends junit.framework.TestCase { static class Nested { // Trigger MSHADE-302 } } ================================================ FILE: src/it/projects/mini-jar-jdk11+/verify.bsh ================================================ /* * 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.io.*; import java.util.jar.*; String[] wanted = { "Main.class", "Main$Nested.class", "junit/framework/TestCase.class", "junit/swingui/icons/error.gif", }; String[] unwanted = { "junit/swingui/TestRunner.class", }; JarFile jarFile = new JarFile( new File( basedir, "target/testmini-1.0.jar" ) ); for ( String path : wanted ) { if ( jarFile.getEntry( path ) == null ) { throw new IllegalStateException( "wanted path is missing: " + path ); } } for ( String path : unwanted ) { if ( jarFile.getEntry( path ) != null ) { throw new IllegalStateException( "unwanted path is present: " + path ); } } jarFile.close(); ================================================ FILE: src/it/projects/mini-jar-malformed-dependencies/invoker.properties ================================================ # 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 = 1.8+ ================================================ FILE: src/it/projects/mini-jar-malformed-dependencies/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade mini-jar-malformed-dependencies-MSHADE-107 1 mini-jar-malformed-dependencies-MSHADE-107 jaxen jaxen 1.1.1 com.ibm.icu icu4j 2.6.1 org.apache.maven.plugins maven-shade-plugin @project.version@ package shade true ================================================ FILE: src/it/projects/mini-jar-package-info/invoker.properties ================================================ # 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 = 1.8+ ================================================ FILE: src/it/projects/mini-jar-package-info/jar-with-package-info/pom.xml ================================================ org.apache.maven.its.shade.mjpi test-package-info 1 4.0.0 dep jar-with-package-info Jar file with a package-info in it. ================================================ FILE: src/it/projects/mini-jar-package-info/jar-with-package-info/src/main/java/org/apache/maven/it/pi/HaveOneClass.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.it.pi; public class HaveOneClass { public static final String CONSTANT = "variable"; } ================================================ FILE: src/it/projects/mini-jar-package-info/jar-with-package-info/src/main/java/org/apache/maven/it/pi/TestPackageAnnotation.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.it.pi; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @Retention(RetentionPolicy.CLASS) public @interface TestPackageAnnotation { } ================================================ FILE: src/it/projects/mini-jar-package-info/jar-with-package-info/src/main/java/org/apache/maven/it/pi/package-info.java ================================================ /* * 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. */ /** * This is some javadoc for the package org.apache.maven.it.pi. * * @since 100 */ @TestPackageAnnotation package org.apache.maven.it.pi; ================================================ FILE: src/it/projects/mini-jar-package-info/pom.xml ================================================ 4.0.0 org.apache.maven.plugins.shade.its shade-parent 1.0 ../setup-parent org.apache.maven.its.shade.mjpi test-package-info 1 pom mini-jar-with-package-info Test for minimizeJar keeping package-info around. jar-with-package-info test org.apache.maven.plugins maven-compiler-plugin @version.maven-compiler-plugin@ org.apache.maven.plugins maven-shade-plugin @project.version@ ================================================ FILE: src/it/projects/mini-jar-package-info/test/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.mjpi test-package-info 1 test test-shade-with-package-info Test that artifact contents can be filtered automatically to produce a mini jar that only contains the referenced classes including package-info.java. org.apache.maven.its.shade.mjpi dep 1 org.apache.maven.plugins maven-shade-plugin attach-shade package shade false true ================================================ FILE: src/it/projects/mini-jar-package-info/test/src/main/java/org/apache/maven/it/pi/Main.java ================================================ package org.apache.maven.it.pi; /* * 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 extends HaveOneClass { } ================================================ FILE: src/it/projects/mini-jar-package-info/verify.bsh ================================================ /* * 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.io.*; import java.util.jar.*; String[] wanted = { "org/apache/maven/it/pi/Main.class", "org/apache/maven/it/pi/HaveOneClass.class", "org/apache/maven/it/pi/package-info.class", }; String[] unwanted = { }; JarFile jarFile = new JarFile( new File( basedir, "test/target/test-1.jar" ) ); for ( String path : wanted ) { if ( jarFile.getEntry( path ) == null ) { throw new IllegalStateException( "wanted path is missing: " + path ); } } for ( String path : unwanted ) { if ( jarFile.getEntry( path ) != null ) { throw new IllegalStateException( "unwanted path is present: " + path ); } } jarFile.close(); ================================================ FILE: src/it/projects/mini-jar-respect-includes/invoker.properties ================================================ # 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 = 1.8+ ================================================ FILE: src/it/projects/mini-jar-respect-includes/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.mj test 1.0 jar MSHADE-111 Prevent minimizeJar from excluding classes that were specifically included with filters. junit junit 4.13.2 org.jdom jdom2 2.0.6.1 org.ow2.asm asm @asmVersion@ org.apache.maven.plugins maven-compiler-plugin @version.maven-compiler-plugin@ org.apache.maven.plugins maven-shade-plugin @project.version@ attach-shade package shade false true junit:junit junit/framework/** junit/awtui/** junit/runner/**/*.properties junit/runner/**/*.gif junit/swingui/icons/*.gif org.jdom:jdom2 ** ================================================ FILE: src/it/projects/mini-jar-respect-includes/src/main/java/Main.java ================================================ /* * 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 extends junit.framework.TestCase { } ================================================ FILE: src/it/projects/mini-jar-respect-includes/verify.bsh ================================================ /* * 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.io.*; import java.util.jar.*; String[] wanted = { "Main.class", "junit/framework/TestCase.class", "junit/runner/logo.gif", "junit/framework/Assert.class", "org/jdom2/Document.class" }; String[] unwanted = { "junit/textui/TestRunner.class", "org/objectweb/asm/Type.class" }; JarFile jarFile = new JarFile( new File( basedir, "target/test-1.0.jar" ) ); for ( String path : wanted ) { if ( jarFile.getEntry( path ) == null ) { throw new IllegalStateException( "wanted path is missing: " + path ); } } for ( String path : unwanted ) { if ( jarFile.getEntry( path ) != null ) { throw new IllegalStateException( "unwanted path is present: " + path ); } } jarFile.close(); ================================================ FILE: src/it/projects/mshade-123/assembly.xml ================================================ zip zip true sample.txt / ================================================ FILE: src/it/projects/mshade-123/invoker.properties ================================================ # 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 = 1.8+ ================================================ FILE: src/it/projects/mshade-123/pom.xml ================================================ test 4.0.0 org.test test 0.0.1-SNAPSHOT jar org.sonatype.oss oss-parent 7 commons-lang commons-lang 2.6 compile org.apache.maven.plugins maven-compiler-plugin @version.maven-compiler-plugin@ 1.8 1.8 org.apache.maven.plugins maven-source-plugin 2.1.2 attach-sources jar org.apache.maven.plugins maven-shade-plugin @project.version@ package shade true commons-lang:commons-lang com.apache.commons.lang org.test.common.lang maven-assembly-plugin @version.maven-assembly-plugin@ false ${project.build.directory}/releases/ ${basedir}/assembly.xml package single ================================================ FILE: src/it/projects/mshade-123/sample.txt ================================================ SAMPLE FILE ================================================ FILE: src/it/projects/non-runtime-scope-excluded/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.nrse it 1.0 jar MSHADE Test that dependencies not matching runtime scope are automatically excluded. org.apache.maven.its.shade.nrse system 1.0 system ${basedir}/system.jar org.apache.maven.its.shade.nrse provided 1.0 provided org.apache.maven.its.shade.nrse compile 1.0 compile org.apache.maven.its.shade.nrse runtime 1.0 runtime org.apache.maven.its.shade.nrse test 1.0 test org.apache.maven.plugins maven-shade-plugin @project.version@ attach-shade package shade false ================================================ FILE: src/it/projects/non-runtime-scope-excluded/verify.bsh ================================================ /* * 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.io.*; import java.util.jar.*; String[] wanted = { "compile.properties", "runtime.properties", }; String[] unwanted = { "system.properties", "provided.properties", "test.properties", }; JarFile jarFile = new JarFile( new File( basedir, "target/it-1.0.jar" ) ); for ( String path : wanted ) { if ( jarFile.getEntry( path ) == null ) { throw new IllegalStateException( "wanted path is missing: " + path ); } } for ( String path : unwanted ) { if ( jarFile.getEntry( path ) != null ) { throw new IllegalStateException( "unwanted path is present: " + path ); } } jarFile.close(); ================================================ FILE: src/it/projects/plugin-descriptor-relocation/app/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.cdr mshade-135 1.0 maven-plugin org.apache.maven.its.shade.cdr comp 0.1 org.apache.maven maven-plugin-api 3.0 org.apache.maven.plugin-tools maven-plugin-annotations 3.2 provided org.apache.maven.plugins maven-compiler-plugin @version.maven-compiler-plugin@ org.apache.maven.plugins maven-plugin-plugin 3.2 true mojo-descriptor descriptor org.apache.maven.plugins maven-shade-plugin @project.version@ shade package shade false org.apache.maven.component.api hidden.api org.apache.maven.component.impl hidden.impl org.apache.maven.test hidden.impl ================================================ FILE: src/it/projects/plugin-descriptor-relocation/app/src/main/java/org/apache/maven/test/Entry.java ================================================ package org.apache.maven.test; /* * 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 Entry { } ================================================ FILE: src/it/projects/plugin-descriptor-relocation/app/src/main/java/org/apache/maven/test/TestMojo.java ================================================ package org.apache.maven.test; /* * 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.List; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.Component; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; @Mojo( name = "test" ) public class TestMojo extends AbstractMojo { @Component private org.apache.maven.component.api.Component component; @Parameter private Entry entry; public void execute() throws MojoExecutionException, MojoFailureException { } } ================================================ FILE: src/it/projects/plugin-descriptor-relocation/lib/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.cdr comp 0.1 jar maven-core-it file:///${basedir}/repo . pom.xml src/** src/main/resources ================================================ FILE: src/it/projects/plugin-descriptor-relocation/lib/src/main/java/org/apache/maven/component/api/Component.java ================================================ package org.apache.maven.component.api; /* * 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 interface Component { String getId(); } ================================================ FILE: src/it/projects/plugin-descriptor-relocation/lib/src/main/java/org/apache/maven/component/impl/DefaultComponent.java ================================================ package org.apache.maven.component.impl; /* * 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 org.apache.maven.component.api.*; public class DefaultComponent implements Component { public String getId() { return "default"; } } ================================================ FILE: src/it/projects/plugin-descriptor-relocation/lib/src/main/resources/META-INF/plexus/components.xml ================================================ 4.0.0 org.apache.maven.its.shade.cdr aggregator 1.0 pom MSHADE-135 Test that plugin descriptors get adjusted to account for relocation of role/impl classes. lib app ================================================ FILE: src/it/projects/plugin-descriptor-relocation/verify.groovy ================================================ /* * 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 groovy.xml.XmlSlurper def shadedJar = new File( basedir, "app/target/mshade-135-1.0.jar") def pluginXml = new URL( "jar:" + shadedJar.toURL() + "!/META-INF/maven/plugin.xml" ) def plugin = new XmlSlurper().parse( pluginXml.openStream() ); assert plugin.mojos.mojo[0].implementation == "hidden.impl.TestMojo"; assert plugin.mojos.mojo[0].parameters.parameter[0].type == "hidden.impl.Entry"; assert plugin.mojos.mojo[0].requirements.requirement[0].role == "hidden.api.Component"; ================================================ FILE: src/it/projects/pom-packaging/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.pp test 1.0 pom MSHADE-52 Test that usage of the plugin within a POM project is supported. Think about Shade being used to create some archive that is not meant to be deployed on its own but to be included in some final/bigger assembly. junit junit 3.8.2 org.apache.maven.plugins maven-shade-plugin @project.version@ create-shaded-bundle-of-some-artifacts-for-inclusion-in-assembly package shade ${project.build.directory}/shaded.jar ================================================ FILE: src/it/projects/pom-packaging/verify.bsh ================================================ /* * 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.io.*; import java.util.jar.*; String[] wanted = { "junit/framework/TestCase.class", }; String[] unwanted = { }; JarFile jarFile = new JarFile( new File( basedir, "target/shaded.jar" ) ); for ( String path : wanted ) { if ( jarFile.getEntry( path ) == null ) { throw new IllegalStateException( "wanted path is missing: " + path ); } } for ( String path : unwanted ) { if ( jarFile.getEntry( path ) != null ) { throw new IllegalStateException( "unwanted path is present: " + path ); } } jarFile.close(); ================================================ FILE: src/it/projects/project-with-reactors-included/invoker.properties ================================================ # 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.goals=clean package ================================================ FILE: src/it/projects/project-with-reactors-included/one/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.pp reactors-included 1.0-SNAPSHOT one one org.junit.jupiter junit-jupiter-api test ================================================ FILE: src/it/projects/project-with-reactors-included/one/src/main/java/org/apache/maven/plugins/shade/its/one/App.java ================================================ package org.apache.maven.plugins.shade.its.one; /* * 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. */ /** * Hello world! * */ public class App { public static void main( String[] args ) { System.out.println( "Hello World!" ); } } ================================================ FILE: src/it/projects/project-with-reactors-included/one/src/main/java/org/apache/maven/plugins/shade/its/one/AppOne.java ================================================ package org.apache.maven.plugins.shade.its.one; /* * 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. */ /** * Hello world! * */ public class AppOne { public static void main( String[] args ) { System.out.println( "Hello World!" ); } } ================================================ FILE: src/it/projects/project-with-reactors-included/one/src/test/java/org/apache/maven/plugins/shade/its/one/AppTest.java ================================================ package org.apache.maven.plugins.shade.its.one; /* * 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 org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertTrue; /** * Unit test for simple App. */ public class AppTest { /** * Rigourous Test :-) */ @Test public void testApp() { assertTrue(true); } } ================================================ FILE: src/it/projects/project-with-reactors-included/pom.xml ================================================ 4.0.0 org.apache.maven.plugins.shade.its shade-parent 1.0 ../setup-parent org.apache.maven.its.shade.pp reactors-included 1.0-SNAPSHOT pom UTF-8 MSHADE-75 org.junit.jupiter junit-jupiter-api 5.14.0 test org.apache.maven.its.shade.pp one ${project.version} one two ================================================ FILE: src/it/projects/project-with-reactors-included/two/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.pp reactors-included 1.0-SNAPSHOT two two org.apache.maven.its.shade.pp one org.junit.jupiter junit-jupiter-api test org.apache.maven.plugins maven-shade-plugin @project.version@ attach-shade package shade false org.apache.maven.its.shade.pp:one ================================================ FILE: src/it/projects/project-with-reactors-included/two/src/main/java/org/apache/maven/plugins/shade/its/two/App.java ================================================ package org.apache.maven.plugins.shade.its.two; /* * 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. */ /** * Hello world! * */ public class App { public static void main( String[] args ) { System.out.println( "Hello World!" ); } } ================================================ FILE: src/it/projects/project-with-reactors-included/two/src/test/java/org/apache/maven/plugins/shade/its/two/AppTest.java ================================================ package org.apache.maven.plugins.shade.its.two; /* * 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 org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertTrue; /** * Unit test for simple App. */ public class AppTest { /** * Rigourous Test :-) */ @Test public void testApp() { assertTrue(true); } } ================================================ FILE: src/it/projects/project-with-reactors-included/verify.bsh ================================================ /* * 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.io.*; import java.util.jar.*; import org.codehaus.plexus.util.*; String[] wanted = { "org/apache/maven/plugins/shade/its/one/AppOne.class", "org/apache/maven/plugins/shade/its/one/App.class", "org/apache/maven/plugins/shade/its/two/App.class" }; JarFile jarFile = new JarFile( new File( basedir, "two/target/two-1.0-SNAPSHOT.jar" ) ); for ( String path : wanted ) { if ( jarFile.getEntry( path ) == null ) { throw new IllegalStateException( "wanted path is missing: " + path ); } } jarFile.close(); // MSHADE-225 Writing output only once File logFile = new File( basedir, "build.log" ); String log = FileUtils.fileRead( logFile ); int index = log.indexOf( "[INFO] Dependency-reduced POM written at: " ); if ( log.indexOf( "[INFO] Dependency-reduced POM written at: ", index+1 ) >= 0 ) { throw new IllegalStateException( "'[INFO] Dependency-reduced POM written at: ' written more than once" + path ); } ================================================ FILE: src/it/projects/reloc-abs-resource-path/pom.xml ================================================ 4.0.0 org.apache.maven.plugins.shade.its shade-parent 1.0 ../setup-parent org.apache.maven.its.shade reloc-abs-resource-path 1.0 MSHADE-119 Test that classes in strings like "/org/apache/velocity/my.properties" get properly relocated in calls to Class.getResource(). org.apache.maven.plugins maven-shade-plugin @project.version@ shade package shade false org.apache.maven.from org.apache.maven.to org.codehaus.mojo exec-maven-plugin 1.1.1 run verify exec ${JAVA_HOME}/bin/java -classpath ${project.build.directory}/reloc-abs-resource-path-1.0.jar Main ================================================ FILE: src/it/projects/reloc-abs-resource-path/src/main/java/Main.java ================================================ import java.net.URL; /* * 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 ) throws Exception { new Main().testAbsResource(); } private void testAbsResource() throws Exception { URL r = getClass().getResource("/org/apache/maven/from/test.properties"); // expect NPE if MSHADE-119 is not fixed. System.out.println( r.toString() ); } } ================================================ FILE: src/it/projects/reloc-abs-resource-path/src/main/resources/org/apache/maven/from/test.properties ================================================ # 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. testprop=proptest ================================================ FILE: src/it/projects/reloc-abs-resource-path-exclude/pom.xml ================================================ 4.0.0 org.apache.maven.plugins.shade.its shade-parent 1.0 ../setup-parent org.apache.maven.its.shade reloc-abs-resource-path-exclude 1.0 MSHADE-119 Test that classes in strings like "/org/apache/velocity/my.properties" get properly relocated in calls to Class.getResource(), taking into account excluded patterns. org.apache.maven.plugins maven-shade-plugin @project.version@ shade package shade false org.apache.maven.from org.apache.maven.to org.apache.maven.from.a.* org.codehaus.mojo exec-maven-plugin 1.1.1 run verify exec ${JAVA_HOME}/bin/java -classpath ${project.build.directory}/reloc-abs-resource-path-exclude-1.0.jar Main ================================================ FILE: src/it/projects/reloc-abs-resource-path-exclude/src/main/java/Main.java ================================================ import java.net.URL; /* * 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 ) throws Exception { new Main().testAbsResource(); } private void testAbsResource() throws Exception { URL r = getClass().getResource("/org/apache/maven/from/a/test.properties"); // expect NPE if from/a was shaded even though it was excluded System.out.println( r.toString() ); r = getClass().getResource("/org/apache/maven/to/b/test.properties"); // expect NPE if from/b was not shaded System.out.println( r.toString() ); } } ================================================ FILE: src/it/projects/reloc-abs-resource-path-exclude/src/main/resources/org/apache/maven/from/a/test.properties ================================================ # 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. testprop=proptest ================================================ FILE: src/it/projects/reloc-abs-resource-path-exclude/src/main/resources/org/apache/maven/from/b/test.properties ================================================ # 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. testprop2=proptest2 ================================================ FILE: src/it/projects/reloc-and-mini/invoker.properties ================================================ # 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 = 1.8+ ================================================ FILE: src/it/projects/reloc-and-mini/pom.xml ================================================ 4.0.0 org.apache.maven.plugins.shade.its shade-parent 1.0 ../setup-parent org.apache.maven.its.shade.mini test 1.0 jar MSHADE-327 Test handling of relocations and minification. junit junit 3.8.2 org.apache.maven.plugins maven-shade-plugin @project.version@ attach-shade package shade true false junit.framework a.junit.framework ================================================ FILE: src/it/projects/reloc-and-mini/src/main/java/org/apache/maven/plugins/shade/its/App.java ================================================ package org.apache.maven.plugins.shade.its; /* * 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 junit.framework.TestResult; public class App { public static void main( String[] args ) { TestResult result = new TestResult(); System.out.println("Failures: " + result.failureCount()); } } ================================================ FILE: src/it/projects/reloc-and-mini/verify.bsh ================================================ /* * 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.io.*; import java.util.jar.*; String[] wanted = { "a/junit/framework/TestResult.class", }; String[] unwanted = { "junit/framework/TestResult.class", }; JarFile jarFile = new JarFile( new File( basedir, "target/test-1.0.jar" ) ); for ( String path : wanted ) { if ( jarFile.getEntry( path ) == null ) { throw new IllegalStateException( "wanted path is missing: " + path ); } } for ( String path : unwanted ) { if ( jarFile.getEntry( path ) != null ) { throw new IllegalStateException( "unwanted path is present: " + path ); } } jarFile.close(); ================================================ FILE: src/it/projects/reloc-anno/invoker.properties ================================================ # 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 = 1.5+ ================================================ FILE: src/it/projects/reloc-anno/pom.xml ================================================ 4.0.0 org.apache.maven.plugins.shade.its shade-parent 1.0 ../setup-parent org.apache.maven.its.shade.ra test 1.0 jar MSHADE-79 Test that annotations are properly relocated. org.apache.maven.plugins maven-compiler-plugin @version.maven-compiler-plugin@ org.apache.maven.plugins maven-jar-plugin @version.maven-jar-plugin@ org.apache.maven.plugins maven-resources-plugin @version.maven-resources-plugin@ org.apache.maven.plugins maven-shade-plugin @project.version@ shade package shade false relocated hidden org.codehaus.mojo exec-maven-plugin 1.1.1 run verify exec ${JAVA_HOME}/bin/java -classpath ${project.build.directory}/test-1.0.jar Main org.apache.maven.plugins maven-surefire-plugin @version.maven-surefire@ ================================================ FILE: src/it/projects/reloc-anno/src/main/java/Main.java ================================================ /* * 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.lang.reflect.*; import relocated.*; @MyAnno public class Main { @MyAnno public String field = ""; @MyAnno public Main() { } @MyAnno public void method() { } public static void main( String[] args ) throws Exception { Class type = Main.class; Field field = type.getField( "field" ); Method method = type.getMethod( "method" ); Constructor constructor = type.getConstructor(); AnnotatedElement[] elements = { type, method, constructor, field }; for ( AnnotatedElement element : elements ) { if ( !element.isAnnotationPresent( MyAnno.class ) ) { throw new IllegalStateException( "annotation missing on " + element ); } } } } ================================================ FILE: src/it/projects/reloc-anno/src/main/java/relocated/MyAnno.java ================================================ package relocated; /* * 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. */ @java.lang.annotation.Retention( java.lang.annotation.RetentionPolicy.RUNTIME ) public @interface MyAnno { } ================================================ FILE: src/it/projects/reloc-class-from-string-pool/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.rcfsp test 1.0 jar MSHADE-47 Test that classes in strings like "[Lnet/sf/cglib/proxy/Callback" get properly relocated. org.apache.maven.plugins maven-compiler-plugin @version.maven-compiler-plugin@ org.apache.maven.plugins maven-jar-plugin @version.maven-jar-plugin@ org.apache.maven.plugins maven-resources-plugin @version.maven-resources-plugin@ org.apache.maven.plugins maven-shade-plugin @project.version@ shade package shade false relocated hidden org.codehaus.mojo exec-maven-plugin 1.1.1 run verify exec ${JAVA_HOME}/bin/java -classpath ${project.build.directory}/test-1.0.jar Main org.apache.maven.plugins maven-surefire-plugin @version.maven-surefire@ ================================================ FILE: src/it/projects/reloc-class-from-string-pool/src/main/java/Main.java ================================================ /* * 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 ) throws Exception { testClassWithSlashes(); testClassWithDots(); testArrayClassWithDots(); testArrayClassWithDots(); } private static void testClassWithSlashes() throws Exception { String typeName = "Lrelocated/RelocatedClass;"; typeName = typeName.substring( 1, typeName.length() - 1 ); typeName = typeName.replace( '/', '.' ); Class type = Class.forName( typeName ); System.out.println( type.getName() ); } private static void testClassWithDots() throws Exception { String typeName = "Lrelocated.RelocatedClass;"; typeName = typeName.substring( 1, typeName.length() - 1 ); typeName = typeName.replace( '/', '.' ); Class type = Class.forName( typeName ); System.out.println( type.getName() ); } private static void testArrayClassWithSlashes() throws Exception { String typeName = "[[[Lrelocated/RelocatedClass;"; typeName = typeName.substring( 4, typeName.length() - 1 ); typeName = typeName.replace( '/', '.' ); Class type = Class.forName( typeName ); System.out.println( type.getName() ); } private static void testArrayClassWithDots() throws Exception { String typeName = "[[[[Lrelocated.RelocatedClass;"; typeName = typeName.substring( 5, typeName.length() - 1 ); typeName = typeName.replace( '/', '.' ); Class type = Class.forName( typeName ); System.out.println( type.getName() ); } } ================================================ FILE: src/it/projects/reloc-class-from-string-pool/src/main/java/relocated/RelocatedClass.java ================================================ package relocated; /* * 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 RelocatedClass { } ================================================ FILE: src/it/projects/reloc-enum-ref-from-anno/invoker.properties ================================================ # 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 = 1.5+ ================================================ FILE: src/it/projects/reloc-enum-ref-from-anno/pom.xml ================================================ 4.0.0 org.apache.maven.plugins.shade.its shade-parent 1.0 ../setup-parent org.apache.maven.its.shade.rerfa test 1.0 jar MSHADE-64 Test that enum references in annotations are properly relocated. org.apache.maven.plugins maven-compiler-plugin @version.maven-compiler-plugin@ org.apache.maven.plugins maven-jar-plugin @version.maven-jar-plugin@ org.apache.maven.plugins maven-resources-plugin @version.maven-resources-plugin@ org.apache.maven.plugins maven-shade-plugin @project.version@ shade package shade false relocated hidden org.codehaus.mojo exec-maven-plugin 1.1.1 run verify exec ${JAVA_HOME}/bin/java -classpath ${project.build.directory}/test-1.0.jar Main org.apache.maven.plugins maven-surefire-plugin @version.maven-surefire@ ================================================ FILE: src/it/projects/reloc-enum-ref-from-anno/src/main/java/Main.java ================================================ /* * 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. */ @MyAnno( relocated.MyEnum.YES ) public class Main { public static void main( String[] args ) throws Exception { MyAnno anno = Main.class.getAnnotation( MyAnno.class ); System.out.println( "ANNO: " + anno.value() ); if ( !relocated.MyEnum.YES.equals( anno.value() ) ) { throw new IllegalStateException( "unexpected value: " + anno.value() ); } } } ================================================ FILE: src/it/projects/reloc-enum-ref-from-anno/src/main/java/MyAnno.java ================================================ /* * 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. */ @java.lang.annotation.Retention( java.lang.annotation.RetentionPolicy.RUNTIME ) public @interface MyAnno { relocated.MyEnum value(); } ================================================ FILE: src/it/projects/reloc-enum-ref-from-anno/src/main/java/relocated/MyEnum.java ================================================ package relocated; /* * 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 enum MyEnum { YES, NO } ================================================ FILE: src/it/projects/reloc-includes-excludes/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.rie test 1.0 jar MSHADE-74 Test handling of inclusions/exclusions for relocations. junit junit 3.8.2 org.apache.maven.plugins maven-shade-plugin @project.version@ attach-shade package shade false junit.textui a junit.textui.TestRunner junit.framework b junit.framework.Test* ================================================ FILE: src/it/projects/reloc-includes-excludes/verify.bsh ================================================ /* * 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.io.*; import java.util.jar.*; String[] wanted = { "a/ResultPrinter.class", "junit/textui/TestRunner.class", "b/Test.class", "b/TestCase.class", "junit/framework/Assert.class", }; String[] unwanted = { "junit/textui/ResultPrinter.class", "junit/framework/Test.class", "junit/framework/TestCase.class", }; JarFile jarFile = new JarFile( new File( basedir, "target/test-1.0.jar" ) ); for ( String path : wanted ) { if ( jarFile.getEntry( path ) == null ) { throw new IllegalStateException( "wanted path is missing: " + path ); } } for ( String path : unwanted ) { if ( jarFile.getEntry( path ) != null ) { throw new IllegalStateException( "unwanted path is present: " + path ); } } jarFile.close(); ================================================ FILE: src/it/projects/rerun-with-reloc/invoker.properties ================================================ # 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. # NOTE: It's the essential part of the test to re-run the package phase invoker.goals = clean package package ================================================ FILE: src/it/projects/rerun-with-reloc/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.rrwr test 0.1 jar MSHADE-30 Test that re-running the package phase without any code changes in between doesn't cause shading to crash. The potential issue was that the first run produced the shaded artifact and that this artifact survived unchanged until shading got executed the second time, thereby re-shading all classes that were included during the first run. org.apache.maven.plugins maven-compiler-plugin @version.maven-compiler-plugin@ org.apache.maven.plugins maven-compiler-plugin @version.maven-compiler-plugin@ 5000 org.apache.maven.plugins maven-install-plugin @version.maven-install-plugin@ org.apache.maven.plugins maven-jar-plugin @version.maven-jar-plugin@ false org.apache.maven.plugins maven-resources-plugin @version.maven-resources-plugin@ org.apache.maven.plugins maven-shade-plugin @project.version@ shade package shade false org.apache hidden org.apache.maven.plugins maven-surefire-plugin @version.maven-surefire@ ================================================ FILE: src/it/projects/rerun-with-reloc/src/main/java/org/MyInterface.java ================================================ package org; /* * 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. */ /* * NOTE: The project's main artifact must not be empty! */ public interface MyInterface { } ================================================ FILE: src/it/projects/rerun-with-reloc/src/main/resources/some-ordinary-resource.txt ================================================ ================================================ FILE: src/it/projects/rerun-without-reloc/invoker.properties ================================================ # 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. # NOTE: It's the essential part of the test to re-run the package phase invoker.goals = clean package package ================================================ FILE: src/it/projects/rerun-without-reloc/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.rrwor test 0.1 jar MSHADE-30 Test that re-running the package phase without any code changes in between doesn't cause shading to crash. The potential issue was that the first run produced the shaded artifact and that this artifact survived unchanged until shading got executed the second time, thereby re-shading all classes that were included during the first run. org.apache.maven.plugins maven-compiler-plugin @version.maven-compiler-plugin@ org.apache.maven.plugins maven-compiler-plugin @version.maven-compiler-plugin@ 5000 org.apache.maven.plugins maven-install-plugin @version.maven-install-plugin@ org.apache.maven.plugins maven-jar-plugin @version.maven-jar-plugin@ false org.apache.maven.plugins maven-resources-plugin @version.maven-resources-plugin@ org.apache.maven.plugins maven-shade-plugin @project.version@ shade package shade false org.apache.maven.plugins maven-surefire-plugin @version.maven-surefire@ ================================================ FILE: src/it/projects/rerun-without-reloc/src/main/java/org/MyInterface.java ================================================ package org; /* * 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. */ /* * NOTE: The project's main artifact must not be empty! */ public interface MyInterface { } ================================================ FILE: src/it/projects/rerun-without-reloc/src/main/resources/some-ordinary-resource.txt ================================================ ================================================ FILE: src/it/projects/services-resource-transformer/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.srt test 1.0 MSHADE-76 Test the merging of META-INF/services/** entries. org.apache.maven.its.shade.srt one 0.1 org.apache.maven.its.shade.srt two 0.1 org.apache.maven.plugins maven-shade-plugin @project.version@ attach-shade shade false ================================================ FILE: src/it/projects/services-resource-transformer/verify.bsh ================================================ /* * 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.io.*; import java.util.jar.*; import org.codehaus.plexus.util.*; JarFile jarFile = new JarFile( new File( basedir, "target/test-1.0.jar" ) ); JarEntry jarEntry = jarFile.getEntry( "META-INF/services/org.apache.maven.Shade" ); String service = IOUtil.toString( jarFile.getInputStream( jarEntry ), "UTF-8" ); jarFile.close(); String[] providers = service.split( "(\r\n)|(\r)|(\n)" ); if ( providers.length != 2 ) { throw new IllegalStateException( "Broken provider list: " + service ); } ================================================ FILE: src/it/projects/services-resource-transformer-with-reloc-includes-excludes/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.srt mshade-237 1.0 MSHADE-237 Test the merging of META-INF/services/** entries, when relocation includes/excludes patterns are specified org.apache.maven.its.shade.srt mshade-237-one 0.1 org.apache.maven.its.shade.srt mshade-237-two 0.1 org.apache.maven.plugins maven-shade-plugin @project.version@ attach-shade shade false org.apache.maven.its.shade shaded.org.apache.maven.its.shade org.apache.maven.its.shade.One ================================================ FILE: src/it/projects/services-resource-transformer-with-reloc-includes-excludes/verify.bsh ================================================ /* * 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.io.*; import java.util.Arrays; import java.util.jar.*; import org.codehaus.plexus.util.*; JarFile jarFile = new JarFile( new File( basedir, "target/mshade-237-1.0.jar" ) ); JarEntry jarEntry = jarFile.getEntry( "META-INF/services/org.apache.maven.shade" ); String service = IOUtil.toString( jarFile.getInputStream( jarEntry ), "UTF-8" ); jarFile.close(); String[] services = service.split( "(\r\n)|(\r)|(\n)" ); String[] expected = { "org.apache.maven.its.shade.One", "shaded.org.apache.maven.its.shade.Two" }; Arrays.sort(services); Arrays.sort(expected); if ( !Arrays.equals( services, expected ) ) { throw new IllegalStateException( "Different services than expected: " + service ); } ================================================ FILE: src/it/projects/setup-parent/pom.xml ================================================ 4.0.0 org.apache.maven.plugins.shade.its shade-parent 1.0 pom jdk9 9 ================================================ FILE: src/it/projects/shadePomDependency/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.spom shadePomDependency 1.0 pom MSHADE-60 :: dependency to a type=pom artifact Test creating an uberwar containing an artifact which may not be handled by the JarFile like e.g. a depending pom. The artifact with packaging=pom we depend on has several other artifacts as dependencies. Those artifacts should be contained in the shade-artifact finally. pomDependency shadingModule testModule ================================================ FILE: src/it/projects/shadePomDependency/pomDependency/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.spom pomDependency 1.0 pom MSHADE-60 :: dependency to a packaging=pom artifact This is an artifact with packaging=pom. It only declares further dependencies which should be shaded into the final uberwar. org.apache.maven.plugins maven-compiler-plugin @version.maven-compiler-plugin@ ================================================ FILE: src/it/projects/shadePomDependency/shadingModule/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.spom shadingModule 1.0 MSHADE-60 :: dependency to a type=pom artifact This module creates the uberwar containing an artifact which may not be handled by the JarFile like e.g. a depending pom. The artifact with packaging=pom we depend on has several other artifacts as dependencies. Those artifacts should be contained in the shade-artifact finally. org.apache.maven.its.shade.spom pomDependency 1.0 pom org.apache.maven.plugins maven-shade-plugin @project.version@ create-shaded-artifact package shade true shaded false ================================================ FILE: src/it/projects/shadePomDependency/testModule/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.spom testModule 1.0 MSHADE-60 :: dependency to a type=pom artifact This module uses the shaded artifact and tries to import a package from the shaded module org.apache.maven.its.shade.spom shadingModule 1.0 shaded ================================================ FILE: src/it/projects/shadePomDependency/testModule/src/main/java/ShadedClassUsage.java ================================================ /* * 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 ShadedClassUsage { public static void main() throws Exception { Class cmClass = Class.forName( "org.apache.maven.plugin.CompilerMojo", true, Thread.currentThread().getContextClassLoader() ); } } ================================================ FILE: src/it/projects/shading-with-java-8-sources/invoker.properties ================================================ # 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 = 1.8+ invoker.goals=clean verify ================================================ FILE: src/it/projects/shading-with-java-8-sources/pom.xml ================================================ 4.0.0 org.apache.maven.plugins.shade.its shading-with-java-8-sources 1.0-SNAPSHOT users-shader-impl junit junit 4.13.2 test maven-compiler-plugin 1.8 1.8 org.apache.maven.plugins maven-shade-plugin @project.version@ org.apache.maven.plugins maven-shade-plugin @project.version@ tests create-shaded-artifact package shade true shaded false org.apache.maven.plugins.shade.its hidden org.codehaus.mojo exec-maven-plugin 1.1.1 run verify exec ${java.home}/bin/java -classpath ${project.build.directory}/shading-with-java-8-sources-1.0-SNAPSHOT-shaded.jar hidden.App ================================================ FILE: src/it/projects/shading-with-java-8-sources/src/main/java/org/apache/maven/plugins/shade/its/App.java ================================================ package org.apache.maven.plugins.shade.its; /* * 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. */ /** * Hello world! */ public class App { public static void main( String[] args ) { System.out.println( "=== RunnableTest ===" ); // Anonymous Runnable Runnable r1 = new Runnable() { @Override public void run() { System.out.println( "Hello world one!" ); } }; // Lambda Runnable Runnable r2 = () -> System.out.println( "Hello world two!" ); // Run em! r1.run(); r2.run(); } } ================================================ FILE: src/it/projects/shading-with-java-8-sources/verify.groovy ================================================ /* * 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. */ assert new File(basedir, 'build.log').exists(); content = new File(basedir, 'build.log').text; assert content.contains( '=== RunnableTest ==='); assert content.contains( 'Hello world one!'); assert content.contains( 'Hello world two!'); ================================================ FILE: src/it/projects/shading-with-release-sources/invoker.properties ================================================ # 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 = 9+ invoker.goals=clean verify ================================================ FILE: src/it/projects/shading-with-release-sources/pom.xml ================================================ 4.0.0 org.apache.maven.plugins.shade.its shading-with-java-11-sources 1.0-SNAPSHOT users-shader-impl junit junit 4.13.2 test maven-compiler-plugin @version.maven-compiler-plugin@ ${java.specification.version} org.apache.maven.plugins maven-shade-plugin @project.version@ org.apache.maven.plugins maven-shade-plugin @project.version@ tests create-shaded-artifact package shade true shaded false org.apache.maven.plugins.shade.its hidden org.codehaus.mojo exec-maven-plugin 1.6.0 run verify exec ${java.home}/bin/java -classpath ${project.build.directory}/shading-with-java-11-sources-1.0-SNAPSHOT-shaded.jar hidden.App ================================================ FILE: src/it/projects/shading-with-release-sources/src/main/java/org/apache/maven/plugins/shade/its/App.java ================================================ package org.apache.maven.plugins.shade.its; /* * 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. */ /** * Hello world! */ public class App { public static void main( String[] args ) { System.out.println( "=== RunnableTest ===" ); // Anonymous Runnable Runnable r1 = new Runnable() { @Override public void run() { System.out.println( "Hello world one!" ); } }; // Lambda Runnable Runnable r2 = () -> System.out.println( "Hello world two!" ); // Run em! r1.run(); r2.run(); } } ================================================ FILE: src/it/projects/shading-with-release-sources/verify.groovy ================================================ /* * 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. */ assert new File(basedir, 'build.log').exists(); content = new File(basedir, 'build.log').text; assert content.contains( '=== RunnableTest ==='); assert content.contains( 'Hello world one!'); assert content.contains( 'Hello world two!'); ================================================ FILE: src/it/projects/users-shader-impl/invoker.properties ================================================ # 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.goals=clean package ================================================ FILE: src/it/projects/users-shader-impl/pom.xml ================================================ 4.0.0 org.apache.maven.plugins.shade.its shade-parent 1.0 ../setup-parent org.apache.maven.plugins.shade.its users-shader-impl 1.0-SNAPSHOT users-shader-impl org.junit.jupiter junit-jupiter-api 5.14.0 test org.apache.maven.plugins maven-shade-plugin @project.version@ org.apache.maven.plugins maven-shade-plugin @project.version@ tests create-shaded-artifact package shade mock true shaded false ================================================ FILE: src/it/projects/users-shader-impl/src/main/java/org/apache/maven/plugins/shade/its/App.java ================================================ package org.apache.maven.plugins.shade.its; /* * 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. */ /** * Hello world! * */ public class App { public static void main( String[] args ) { System.out.println( "Hello World!" ); } } ================================================ FILE: src/it/projects/users-shader-impl/src/test/java/org/apache/maven/plugins/shade/its/AppTest.java ================================================ package org.apache.maven.plugins.shade.its; /* * 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 org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertTrue; /** * Unit test for simple App. */ public class AppTest { /** * Create the test case * * @param testName name of the test case */ /** * Rigourous Test :-) */ @Test public void testApp() { assertTrue(true); } } ================================================ FILE: src/it/projects/users-shader-impl/verify.groovy ================================================ /* * 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. */ assert new File(basedir, 'build.log').exists(); content = new File(basedir, 'build.log').text; assert content.contains( 'Executing MockShader#shade'); return true; ================================================ FILE: src/it/projects/xml-transformer-ignores-dtd/pom.xml ================================================ 4.0.0 org.apache.maven.its.shade.xartid test 1.0 jar MSHADE-59 Test that XmlAppendingResourceTransformer ignores DTD by default to avoid potential problematic network access. org.apache.maven.plugins maven-shade-plugin @project.version@ attach-shade package shade false test.xml ================================================ FILE: src/it/projects/xml-transformer-ignores-dtd/src/main/resources/test.xml ================================================ ================================================ FILE: src/it/projects/xml-transformer-ignores-dtd/verify.bsh ================================================ /* * 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.io.*; import java.util.jar.*; String[] wanted = { "test.xml", }; JarFile jarFile = new JarFile( new File( basedir, "target/test-1.0.jar" ) ); for ( String path : wanted ) { if ( jarFile.getEntry( path ) == null ) { throw new IllegalStateException( "wanted path is missing: " + path ); } } jarFile.close(); ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/DefaultShader.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade; import javax.inject.Named; import javax.inject.Singleton; import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PushbackInputStream; import java.io.Writer; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Collection; import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; 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; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.zip.CRC32; import java.util.zip.ZipEntry; import java.util.zip.ZipException; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugins.shade.filter.Filter; import org.apache.maven.plugins.shade.relocation.Relocator; import org.apache.maven.plugins.shade.resource.ManifestResourceTransformer; import org.apache.maven.plugins.shade.resource.ReproducibleResourceTransformer; import org.apache.maven.plugins.shade.resource.ResourceTransformer; import org.codehaus.plexus.util.IOUtil; import org.codehaus.plexus.util.io.CachingOutputStream; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.commons.ClassRemapper; import org.objectweb.asm.commons.Remapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Jason van Zyl */ @Singleton @Named public class DefaultShader implements Shader { private static final int BUFFER_SIZE = 32 * 1024; private final Logger logger; public DefaultShader() { this(LoggerFactory.getLogger(DefaultShader.class)); } public DefaultShader(final Logger logger) { this.logger = Objects.requireNonNull(logger); } // workaround for MSHADE-420 private long getTime(ZipEntry entry) { if (entry.getLastModifiedTime() == null) { return -1; } long mtime = entry.getLastModifiedTime().toMillis(); if (hasX5455ExtendedTimestamp(entry)) { Calendar cal = Calendar.getInstance(); cal.setTimeInMillis(mtime); mtime = mtime - (cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET)); } return mtime; } /** * Returns {@code true} if passed in {@link ZipEntry} has extra data that contains the extended timestamp (0x5455). * * @see X5455_ExtendedTimestamp */ private static boolean hasX5455ExtendedTimestamp(ZipEntry zipEntry) { if (zipEntry.getExtra() != null) { ByteBuffer extraData = ByteBuffer.wrap(zipEntry.getExtra()); extraData.order(ByteOrder.LITTLE_ENDIAN); while (extraData.hasRemaining()) { int id = extraData.getShort() & 0xffff; int length = extraData.getShort() & 0xffff; if (id == 0x5455) { // Extended TS is present return true; } else { // skip to next extraData.position(extraData.position() + length); } } } return false; } public void shade(ShadeRequest shadeRequest) throws IOException, MojoExecutionException { Set resources = new HashSet<>(); ManifestResourceTransformer manifestTransformer = null; List transformers = new ArrayList<>(shadeRequest.getResourceTransformers()); for (Iterator it = transformers.iterator(); it.hasNext(); ) { ResourceTransformer transformer = it.next(); if (transformer instanceof ManifestResourceTransformer) { manifestTransformer = (ManifestResourceTransformer) transformer; it.remove(); } } final DefaultPackageMapper packageMapper = new DefaultPackageMapper(shadeRequest.getRelocators()); // noinspection ResultOfMethodCallIgnored shadeRequest.getUberJar().getParentFile().mkdirs(); try (JarOutputStream out = new JarOutputStream(new BufferedOutputStream(new CachingOutputStream(shadeRequest.getUberJar())))) { goThroughAllJarEntriesForManifestTransformer(shadeRequest, resources, manifestTransformer, out); // CHECKSTYLE_OFF: MagicNumber Map> duplicates = new HashMap<>(); // CHECKSTYLE_ON: MagicNumber shadeJars(shadeRequest, resources, transformers, out, duplicates, packageMapper); // CHECKSTYLE_OFF: MagicNumber Map, HashSet> overlapping = new HashMap<>(); // CHECKSTYLE_ON: MagicNumber for (String clazz : duplicates.keySet()) { Collection jarz = duplicates.get(clazz); if (jarz.size() > 1) { overlapping.computeIfAbsent(jarz, k -> new HashSet<>()).add(clazz); } } // Log a summary of duplicates logSummaryOfDuplicates(overlapping); if (!overlapping.keySet().isEmpty()) { showOverlappingWarning(); } for (ResourceTransformer transformer : transformers) { if (transformer.hasTransformedResource()) { transformer.modifyOutputStream(out); } } } for (Filter filter : shadeRequest.getFilters()) { filter.finished(); } } /** * {@link InputStream} that can peek ahead at zip header bytes. */ private static class ZipHeaderPeekInputStream extends PushbackInputStream { private static final byte[] ZIP_HEADER = new byte[] {0x50, 0x4b, 0x03, 0x04}; private static final int HEADER_LEN = 4; protected ZipHeaderPeekInputStream(InputStream in) { super(in, HEADER_LEN); } public boolean hasZipHeader() throws IOException { final byte[] header = new byte[HEADER_LEN]; int len = super.read(header, 0, HEADER_LEN); if (len != -1) { super.unread(header, 0, len); } return Arrays.equals(header, ZIP_HEADER); } } /** * Data holder for CRC and Size. */ private static class CrcAndSize { private final CRC32 crc = new CRC32(); private long size; CrcAndSize(InputStream inputStream) throws IOException { load(inputStream); } private void load(InputStream inputStream) throws IOException { byte[] buffer = new byte[BUFFER_SIZE]; int bytesRead; while ((bytesRead = inputStream.read(buffer)) != -1) { this.crc.update(buffer, 0, bytesRead); this.size += bytesRead; } } public void setupStoredEntry(JarEntry entry) { entry.setSize(this.size); entry.setCompressedSize(this.size); entry.setCrc(this.crc.getValue()); entry.setMethod(ZipEntry.STORED); } } private void shadeJars( ShadeRequest shadeRequest, Set resources, List transformers, JarOutputStream jos, Map> duplicates, DefaultPackageMapper packageMapper) throws IOException { for (File jar : shadeRequest.getJars()) { logger.debug("Processing JAR " + jar); List jarFilters = getFilters(jar, shadeRequest.getFilters()); if (jar.isDirectory()) { shadeDir( shadeRequest, resources, transformers, packageMapper, jos, duplicates, jar, jar, "", jarFilters); } else { shadeJar(shadeRequest, resources, transformers, packageMapper, jos, duplicates, jar, jarFilters); } } } @SuppressWarnings("checkstyle:ParameterNumber") private void shadeDir( ShadeRequest shadeRequest, Set resources, List transformers, DefaultPackageMapper packageMapper, JarOutputStream jos, Map> duplicates, File jar, File current, String prefix, List 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) { throw new IOException(String.format("Problem shading JAR %s entry %s: %s", current, name, e), e); } } if (isFiltered(jarFilters, name) || isExcludedEntry(name)) { continue; } try { shadeJarEntry( shadeRequest, resources, transformers, packageMapper, jos, duplicates, jar, new Callable() { @Override public InputStream call() throws Exception { return Files.newInputStream(file.toPath()); } }, name, file.lastModified(), -1 /*ignore*/); } catch (Exception e) { throw new IOException(String.format("Problem shading JAR %s entry %s: %s", current, name, e), e); } } } @SuppressWarnings("checkstyle:ParameterNumber") private void shadeJar( ShadeRequest shadeRequest, Set resources, List transformers, DefaultPackageMapper packageMapper, JarOutputStream jos, Map> duplicates, File jar, List jarFilters) throws IOException { try (JarFile jarFile = newJarFile(jar)) { for (Enumeration j = jarFile.entries(); j.hasMoreElements(); ) { final JarEntry entry = j.nextElement(); String name = entry.getName(); if (entry.isDirectory() || isFiltered(jarFilters, name) || isExcludedEntry(name)) { continue; } try { shadeJarEntry( shadeRequest, resources, transformers, packageMapper, jos, duplicates, jar, new Callable() { @Override public InputStream call() throws Exception { return jarFile.getInputStream(entry); } }, name, getTime(entry), 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; } @SuppressWarnings("checkstyle:ParameterNumber") private void shadeJarEntry( ShadeRequest shadeRequest, Set resources, List transformers, DefaultPackageMapper packageMapper, JarOutputStream jos, Map> duplicates, File jar, Callable inputProvider, String name, long time, int method) throws Exception { try (InputStream in = inputProvider.call()) { String mappedName = packageMapper.map(name, true, false); int idx = mappedName.lastIndexOf('/'); if (idx != -1) { // make sure dirs are created String dir = mappedName.substring(0, idx); if (!resources.contains(dir)) { addDirectory(resources, jos, dir, time); } } duplicates.computeIfAbsent(name, k -> new HashSet<>()).add(jar); if (name.endsWith(".class")) { addRemappedClass(jos, jar, name, time, in, packageMapper); } else if (shadeRequest.isShadeSourcesContent() && name.endsWith(".java")) { // Avoid duplicates if (resources.contains(mappedName)) { return; } addJavaSource(resources, jos, mappedName, time, in, shadeRequest.getRelocators()); } else { if (!resourceTransformed(transformers, mappedName, in, shadeRequest.getRelocators(), time)) { // Avoid duplicates that aren't accounted for by the resource transformers if (resources.contains(mappedName)) { logger.debug("We have a duplicate " + name + " in " + jar); return; } addResource(resources, jos, mappedName, inputProvider, time, method); } else { duplicates.computeIfAbsent(name, k -> new HashSet<>()).remove(jar); } } } } private void goThroughAllJarEntriesForManifestTransformer( ShadeRequest shadeRequest, Set resources, ManifestResourceTransformer manifestTransformer, JarOutputStream jos) throws IOException { if (manifestTransformer != null) { for (File jar : shadeRequest.getJars()) { try (JarFile jarFile = newJarFile(jar)) { for (Enumeration en = jarFile.entries(); en.hasMoreElements(); ) { JarEntry entry = en.nextElement(); String resource = entry.getName(); if (manifestTransformer.canTransformResource(resource)) { resources.add(resource); try (InputStream inputStream = jarFile.getInputStream(entry)) { manifestTransformer.processResource( resource, inputStream, shadeRequest.getRelocators(), getTime(entry)); } break; } } } } if (manifestTransformer.hasTransformedResource()) { manifestTransformer.modifyOutputStream(jos); } } } private void showOverlappingWarning() { logger.warn("maven-shade-plugin has detected that some files are"); logger.warn("present in two or more JARs. When this happens, only one"); logger.warn("single version of the file is copied to the uber jar."); logger.warn("Usually this is not harmful and you can skip these warnings,"); logger.warn("otherwise try to manually exclude artifacts based on"); logger.warn("mvn dependency:tree -Ddetail=true and the above output."); logger.warn("See https://maven.apache.org/plugins/maven-shade-plugin/"); } private void logSummaryOfDuplicates(Map, HashSet> overlapping) { for (Collection jarz : overlapping.keySet()) { List jarzS = new ArrayList<>(); for (File jjar : jarz) { jarzS.add(jjar.getName()); } Collections.sort(jarzS); // deterministic messages to be able to compare outputs (useful on CI) List classes = new LinkedList<>(); List resources = new LinkedList<>(); for (String name : overlapping.get(jarz)) { if (name.endsWith(".class")) { classes.add(name.replace(".class", "").replace("/", ".")); } else { resources.add(name); } } // CHECKSTYLE_OFF: LineLength final Collection overlaps = new ArrayList<>(); if (!classes.isEmpty()) { if (resources.size() == 1) { overlaps.add("class"); } else { overlaps.add("classes"); } } if (!resources.isEmpty()) { if (resources.size() == 1) { overlaps.add("resource"); } else { overlaps.add("resources"); } } final List all = new ArrayList<>(classes.size() + resources.size()); all.addAll(classes); all.addAll(resources); logger.warn(String.join(", ", jarzS) + " define " + all.size() + " overlapping " + String.join(" and ", overlaps) + ": "); // CHECKSTYLE_ON: LineLength Collections.sort(all); int max = 10; for (int i = 0; i < Math.min(max, all.size()); i++) { logger.warn(" - " + all.get(i)); } if (all.size() > max) { logger.warn(" - " + (all.size() - max) + " more..."); } } } private JarFile newJarFile(File jar) throws IOException { try { return new JarFile(jar); } catch (ZipException zex) { // JarFile is not very verbose and doesn't tell the user which file it was // so we will create a new Exception instead throw new ZipException("error in opening zip file " + jar); } } private List getFilters(File jar, List filters) { List list = new ArrayList<>(); for (Filter filter : filters) { if (filter.canFilter(jar)) { list.add(filter); } } return list; } private void addDirectory(Set resources, JarOutputStream jos, String name, long time) throws IOException { if (name.lastIndexOf('/') > 0) { String parent = name.substring(0, name.lastIndexOf('/')); if (!resources.contains(parent)) { addDirectory(resources, jos, parent, time); } } // directory entries must end in "/" JarEntry entry = new JarEntry(name + "/"); entry.setTime(time); jos.putNextEntry(entry); resources.add(name); } private void addRemappedClass( JarOutputStream jos, File jar, String name, long time, InputStream is, DefaultPackageMapper packageMapper) throws IOException, MojoExecutionException { if (packageMapper.relocators.isEmpty()) { try { JarEntry entry = new JarEntry(name); entry.setTime(time); jos.putNextEntry(entry); IOUtil.copy(is, jos); } catch (ZipException e) { logger.debug("We have a duplicate " + name + " in " + jar); } return; } // 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. // Copying the original constant pool should be avoided because it would keep references // to the original class names. This is not a problem at runtime (because these entries in the // constant pool are never used), but confuses some tools such as Felix' maven-bundle-plugin // that use the constant pool to determine the dependencies of a class. ClassWriter cw = new ClassWriter(0); final String pkg = name.substring(0, name.lastIndexOf('/') + 1); final ShadeClassRemapper cv = new ShadeClassRemapper(cw, pkg, packageMapper); try { cr.accept(cv, ClassReader.EXPAND_FRAMES); } catch (Throwable ise) { throw new MojoExecutionException("Error in ASM processing class " + name, ise); } // If nothing was relocated by ShadeClassRemapper, write the original class, otherwise the transformed one final byte[] renamedClass; if (cv.remapped) { logger.debug("Rewrote class bytecode: " + name); renamedClass = cw.toByteArray(); } else { logger.debug("Keeping original class bytecode: " + name); renamedClass = originalClass; } // Need to take the .class off for remapping evaluation String 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. JarEntry entry = new JarEntry(mappedName + ".class"); entry.setTime(time); jos.putNextEntry(entry); jos.write(renamedClass); } catch (ZipException e) { logger.debug("We have a duplicate " + mappedName + " in " + jar); } } private boolean isFiltered(List filters, String name) { for (Filter filter : filters) { if (filter.isFiltered(name)) { return true; } } return false; } private boolean resourceTransformed( List resourceTransformers, String name, InputStream is, List relocators, long time) throws IOException { boolean resourceTransformed = false; for (ResourceTransformer transformer : resourceTransformers) { if (transformer.canTransformResource(name)) { logger.debug("Transforming " + name + " using " + transformer.getClass().getName()); if (transformer instanceof ReproducibleResourceTransformer) { ((ReproducibleResourceTransformer) transformer).processResource(name, is, relocators, time); } else { transformer.processResource(name, is, relocators); } resourceTransformed = true; break; } } return resourceTransformed; } private void addJavaSource( Set resources, JarOutputStream jos, String name, long time, InputStream is, List relocators) throws IOException { JarEntry entry = new JarEntry(name); entry.setTime(time); jos.putNextEntry(entry); String sourceContent = IOUtil.toString(new InputStreamReader(is, StandardCharsets.UTF_8)); for (Relocator relocator : relocators) { sourceContent = relocator.applyToSourceContent(sourceContent); } final Writer writer = new OutputStreamWriter(jos, StandardCharsets.UTF_8); writer.write(sourceContent); writer.flush(); resources.add(name); } private void addResource( Set resources, JarOutputStream jos, String name, Callable input, long time, int method) throws Exception { 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() && method == ZipEntry.STORED) { new CrcAndSize(inputStream).setupStoredEntry(entry); inputStream.close(); inputStream = new ZipHeaderPeekInputStream(input.call()); } entry.setTime(time); jos.putNextEntry(entry); IOUtil.copy(inputStream, jos); resources.add(name); } finally { inputStream.close(); } } private interface PackageMapper { /** * 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}? * @return mapped entity name, e.g. {@code org/apache/acme/Foo} or {@code org.apache.acme.Foo} */ String map(String entityName, boolean mapPaths, boolean mapPackages); } /** * A package mapper based on a list of {@link Relocator}s */ private static class DefaultPackageMapper implements PackageMapper { private static final Pattern CLASS_PATTERN = Pattern.compile("(\\[*)?L(.+);"); private final List relocators; private DefaultPackageMapper(final List relocators) { this.relocators = relocators; } @Override public String map(String entityName, boolean mapPaths, final boolean mapPackages) { String value = entityName; String prefix = ""; String suffix = ""; Matcher m = CLASS_PATTERN.matcher(entityName); if (m.matches()) { prefix = m.group(1) + "L"; suffix = ";"; entityName = m.group(2); } for (Relocator r : relocators) { if (mapPackages && r.canRelocateClass(entityName)) { value = prefix + r.relocateClass(entityName) + suffix; break; } else if (mapPaths && r.canRelocatePath(entityName)) { value = prefix + r.relocatePath(entityName) + suffix; break; } } return value; } } private static class LazyInitRemapper extends Remapper { private PackageMapper relocators; @Override public Object mapValue(Object object) { return object instanceof String ? relocators.map((String) object, true, true) : super.mapValue(object); } @Override public String map(String name) { // NOTE: Before the factoring out duplicate code from 'private String map(String, boolean)', this method did // the same as 'mapValue', except for not trying to replace "dotty" package-like patterns (only "slashy" // path-like ones). The refactoring retains this difference. But actually, all unit and integration tests // still pass, if both variants are unified into one which always tries to replace both pattern types. // // TODO: Analyse if this case is really necessary and has any special meaning or avoids any known problems. // If not, then simplify DefaultShader.PackageMapper.map to only have the String parameter and assume // both boolean ones to always be true. return relocators.map(name, true, false); } } // TODO: we can avoid LazyInitRemapper N instantiations (and use a singleton) // reimplementing ClassRemapper there. // It looks a bad idea but actually enables us to respect our relocation API which has no // consistency with ASM one which can lead to multiple issues for short relocation patterns // plus overcome ClassRemapper limitations we can care about (see its javadoc for details). // // NOTE: very short term we can just reuse the same LazyInitRemapper and let the constructor set it. // since multithreading is not faster in this processing it would be more than sufficient if // caring of this 2 objects per class allocation (but keep in mind the visitor will allocate way more ;)). // Last point which makes it done this way as of now is that perf seems not impacted at all. private static class ShadeClassRemapper extends ClassRemapper implements PackageMapper { private final String pkg; private final PackageMapper packageMapper; private boolean remapped; ShadeClassRemapper( final ClassVisitor classVisitor, final String pkg, final DefaultPackageMapper packageMapper) { super(classVisitor, new LazyInitRemapper() /* can't be init in the constructor with "this" */); this.pkg = pkg; this.packageMapper = packageMapper; // use this to enrich relocators impl with "remapped" logic LazyInitRemapper.class.cast(remapper).relocators = this; } @Override public void visitSource(final String source, final String debug) { if (source == null) { super.visitSource(null, debug); return; } final String fqSource = pkg + source; final String mappedSource = map(fqSource, true, false); final String filename = mappedSource.substring(mappedSource.lastIndexOf('/') + 1); super.visitSource(filename, debug); } @Override public String map(final String entityName, boolean mapPaths, final boolean mapPackages) { final String mapped = packageMapper.map(entityName, true, mapPackages); if (!remapped) { remapped = !mapped.equals(entityName); } return mapped; } } } ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/ShadeRequest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade; import java.io.File; import java.util.List; import java.util.Set; import org.apache.maven.plugins.shade.filter.Filter; import org.apache.maven.plugins.shade.relocation.Relocator; import org.apache.maven.plugins.shade.resource.ResourceTransformer; /** * Parameter object used to pass multitude of args to Shader.shade() * @since 2.0 */ public class ShadeRequest { private Set jars; private File uberJar; private List filters; private List relocators; private List resourceTransformers; private boolean shadeSourcesContent; public Set getJars() { return jars; } /** * Which jars to shade. * * @param jars The jars. */ public void setJars(Set jars) { this.jars = jars; } public File getUberJar() { return uberJar; } /** * Output jar. * * @param uberJar The ueberJar file. */ public void setUberJar(File uberJar) { this.uberJar = uberJar; } public List getFilters() { return filters; } /** * The filters. * * @param filters The filters */ public void setFilters(List filters) { this.filters = filters; } public List getRelocators() { return relocators; } /** * The relocators. * * @param relocators The relocators. */ public void setRelocators(List relocators) { this.relocators = relocators; } public List getResourceTransformers() { return resourceTransformers; } /** * The transformers. * * @param resourceTransformers List of resourceTransformers. */ public void setResourceTransformers(List resourceTransformers) { this.resourceTransformers = resourceTransformers; } public boolean isShadeSourcesContent() { return shadeSourcesContent; } /** * When true, it will attempt to shade the contents of the java source files when creating the sources jar. * When false, it will just relocate the java source files to the shaded paths, but will not modify the * actual contents of the java source files. * * @param shadeSourcesContent {@code true} or {@code false}. */ public void setShadeSourcesContent(boolean shadeSourcesContent) { this.shadeSourcesContent = shadeSourcesContent; } } ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/Shader.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade; import java.io.IOException; import org.apache.maven.plugin.MojoExecutionException; /** * Interface that defines the process of shading. */ public interface Shader { /** * Perform a shading operation. * * @param shadeRequest holds the many parameters to this method * @throws IOException for IO errors reading the thing * @throws MojoExecutionException for anything else that goes wrong. */ void shade(ShadeRequest shadeRequest) throws IOException, MojoExecutionException; } ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/ShadingResult.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade; /** * @author Jason van Zyl */ public class ShadingResult { // no op // olamy: what this class ?? } ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/filter/Filter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.filter; import java.io.File; /** * @author David Blevins */ public interface Filter { /** * @param jar The jar file. * @return true if we can filter false otherwise. */ boolean canFilter(File jar); /** * @param classFile The classFile. * @return true if the file has been filtered false otherwise. */ boolean isFiltered(String classFile); /** * If we are finished. */ void finished(); } ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/filter/MinijarFilter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.filter; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.file.Files; import java.util.Collections; import java.util.Enumeration; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.zip.ZipException; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.DependencyResolutionRequiredException; import org.apache.maven.plugin.logging.Log; import org.apache.maven.project.MavenProject; import org.vafer.jdependency.Clazz; import org.vafer.jdependency.Clazzpath; import org.vafer.jdependency.ClazzpathUnit; import static java.nio.charset.StandardCharsets.UTF_8; /** * A filter that prevents the inclusion of classes not required in the final jar. */ public class MinijarFilter implements Filter { private Log log; private Set removable; private int classesKept; private int classesRemoved; // [MSHADE-209] This is introduced only for testing purposes which shows // there is something wrong with the design of this class. (SoC?) // unfortunately i don't have a better idea at the moment. MinijarFilter(int classesKept, int classesRemoved, Log log) { this.classesKept = classesKept; this.classesRemoved = classesRemoved; this.log = log; } /** * @param project {@link MavenProject} * @param log {@link Log} * @throws IOException in case of error. */ public MinijarFilter(MavenProject project, Log log) throws IOException { this(project, log, Collections.emptyList(), Collections.emptySet()); } /** * @param project {@link MavenProject} * @param log {@link Log} * @param entryPoints * @throws IOException in case of error. */ public MinijarFilter(MavenProject project, Log log, Set entryPoints) throws IOException { this(project, log, Collections.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 simpleFilters, Set entryPoints) throws IOException { this.log = log; File artifactFile = project.getArtifact().getFile(); if (artifactFile != null) { Clazzpath cp = new Clazzpath(); ClazzpathUnit artifactUnit = cp.addClazzpathUnit(Files.newInputStream(artifactFile.toPath()), project.toString()); for (Artifact dependency : project.getArtifacts()) { addDependencyToClasspath(cp, dependency); } removable = cp.getClazzes(); if (removable.remove(new Clazz("module-info"))) { log.warn("Removing module-info from " + artifactFile.getName()); } removePackages(artifactUnit); if (entryPoints.isEmpty()) { removable.removeAll(artifactUnit.getClazzes()); removable.removeAll(artifactUnit.getTransitiveDependencies()); } else { Set artifactUnitClazzes = artifactUnit.getClazzes(); Set 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.emptyList() : simpleFilters); removeServices(project, cp); } } private void removeServices(final MavenProject project, final Clazzpath cp) { boolean repeatScan; do { repeatScan = false; final Set neededClasses = cp.getClazzes(); neededClasses.removeAll(removable); try { // getRuntimeClasspathElements returns a list of // - the build output directory // - all the paths to the dependencies' jars // We thereby need to ignore the build directory because we don't want // to remove anything from it, as it's the starting point of the // minification process. for (final String fileName : project.getRuntimeClasspathElements()) { if (new File(fileName).isDirectory()) { repeatScan |= removeServicesFromDir(cp, neededClasses, fileName); } else { repeatScan |= removeServicesFromJar(cp, neededClasses, fileName); } } } catch (final DependencyResolutionRequiredException e) { log.warn(e.getMessage()); } } while (repeatScan); } private boolean removeServicesFromDir(Clazzpath cp, Set 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 (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 neededClasses, String fileName) { boolean repeatScan = false; try (JarFile jar = new JarFile(fileName)) { for (final Enumeration entries = jar.entries(); entries.hasMoreElements(); ) { final JarEntry jarEntry = entries.nextElement(); if (jarEntry.isDirectory() || !jarEntry.getName().startsWith("META-INF/services/")) { continue; } final String serviceClassName = jarEntry.getName().substring("META-INF/services/".length()); final boolean isNeededClass = neededClasses.contains(cp.getClazz(serviceClassName)); if (!isNeededClass) { continue; } try (BufferedReader configFileReader = new BufferedReader(new InputStreamReader(jar.getInputStream(jarEntry), UTF_8))) { // check whether the found classes use services in turn repeatScan = scanServiceProviderConfigFile(cp, configFileReader); } catch (final IOException e) { log.warn(e.getMessage()); } } } catch (final IOException e) { log.warn("Not a JAR file candidate. Ignoring classpath element '" + fileName + "' (" + e + ")."); } return repeatScan; } private boolean scanServiceProviderConfigFile(Clazzpath cp, BufferedReader configFileReader) throws IOException { boolean serviceClassFound = false; for (String line = configFileReader.readLine(); line != null; line = configFileReader.readLine()) { final String className = line.split("#", 2)[0].trim(); if (className.isEmpty()) { continue; } final Clazz clazz = cp.getClazz(className); if (clazz == null || !removable.contains(clazz)) { continue; } log.debug(className + " was not removed because it is a service"); removeClass(clazz); serviceClassFound = true; } return serviceClassFound; } private void removeClass(final Clazz clazz) { removable.remove(clazz); removable.removeAll(clazz.getTransitiveDependencies()); } private ClazzpathUnit addDependencyToClasspath(Clazzpath cp, Artifact dependency) throws IOException { ClazzpathUnit clazzpathUnit = null; try (InputStream is = new FileInputStream(dependency.getFile())) { clazzpathUnit = cp.addClazzpathUnit(is, dependency.toString()); } catch (ZipException e) { log.warn(dependency.getFile() + " could not be unpacked/read for minimization; dependency is probably malformed."); IOException ioe = new IOException( "Dependency " + dependency + " in file " + dependency.getFile() + " could not be unpacked. File is probably corrupt", e); throw ioe; } catch (ArrayIndexOutOfBoundsException | IllegalArgumentException e) { // trap ArrayIndexOutOfBoundsExceptions caused by malformed dependency classes (MSHADE-107) log.warn(dependency + " could not be analyzed for minimization; dependency is probably malformed."); } return clazzpathUnit; } private void removePackages(ClazzpathUnit artifactUnit) { Set packageNames = new HashSet<>(); removePackages(artifactUnit.getClazzes(), packageNames); removePackages(artifactUnit.getTransitiveDependencies(), packageNames); } private void removePackages(Set clazzes, Set packageNames) { for (Clazz clazz : clazzes) { String name = clazz.getName(); while (name.contains(".")) { name = name.substring(0, name.lastIndexOf('.')); if (packageNames.add(name)) { removable.remove(new Clazz(name + ".package-info")); } } } } private void removeSpecificallyIncludedClasses(MavenProject project, List simpleFilters) throws IOException { // remove classes specifically included in filters Clazzpath checkCp = new Clazzpath(); for (Artifact dependency : project.getArtifacts()) { File jar = dependency.getFile(); for (SimpleFilter simpleFilter : simpleFilters) { if (simpleFilter.canFilter(jar)) { ClazzpathUnit depClazzpathUnit = addDependencyToClasspath(checkCp, dependency); if (depClazzpathUnit != null) { Set clazzes = depClazzpathUnit.getClazzes(); for (final Clazz clazz : new HashSet<>(removable)) { if (clazzes.contains(clazz) // && simpleFilter.isSpecificallyIncluded( clazz.getName().replace('.', '/'))) { log.debug(clazz.getName() + " not removed because it was specifically included"); removeClass(clazz); } } } } } } } @Override public boolean canFilter(File jar) { return true; } @Override public boolean isFiltered(String classFile) { String className = classFile.replace('/', '.').replaceFirst("\\.class$", ""); Clazz clazz = new Clazz(className); if (removable != null && removable.contains(clazz)) { log.debug("Removing " + className); classesRemoved += 1; return true; } classesKept += 1; return false; } @Override public void finished() { int classesTotal = classesRemoved + classesKept; if (classesTotal != 0) { log.info("Minimized " + classesTotal + " -> " + classesKept + " (" + 100 * classesKept / classesTotal + "%)"); } else { log.info("Minimized " + classesTotal + " -> " + classesKept); } } } ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/filter/SimpleFilter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.filter; import java.io.File; import java.util.Collections; import java.util.HashSet; import java.util.Set; import org.apache.maven.plugins.shade.mojo.ArchiveFilter; import org.codehaus.plexus.util.SelectorUtils; /** * @author David Blevins */ /** * @author kama * */ public class SimpleFilter implements Filter { private Set jars; private Set includes; private Set excludes; private boolean excludeDefaults = true; /** * @deprecated As of release 3.2.2, replaced by {@link #SimpleFilter(Set, ArchiveFilter)}} * @param jars set of {@link File}s. * @param includes set of includes. * @param excludes set of excludes. */ @Deprecated public SimpleFilter(Set jars, Set includes, Set excludes) { this(jars, includes, excludes, true); } /** * @param jars set of {@link File}s. * @param archiveFilter set of {@link ArchiveFilter}s. */ public SimpleFilter(final Set jars, final ArchiveFilter archiveFilter) { this(jars, archiveFilter.getIncludes(), archiveFilter.getExcludes(), archiveFilter.getExcludeDefaults()); } /** * @param jars set of {@link File}s. * @param includes set of includes. * @param excludes set of excludes. * @param excludeDefaults whether to exclude default includes once includes are provided explicitly. */ private SimpleFilter( final Set jars, final Set includes, final Set excludes, final boolean excludeDefaults) { this.jars = (jars != null) ? Collections.unmodifiableSet(jars) : Collections.emptySet(); this.includes = normalizePatterns(includes); this.excludes = normalizePatterns(excludes); this.excludeDefaults = excludeDefaults; } /** {@inheritDoc} */ @Override public boolean canFilter(File jar) { return jars.contains(jar); } /** {@inheritDoc} */ @Override public boolean isFiltered(String classFile) { String path = normalizePath(classFile); return !((!excludeDefaults || isIncluded(path)) && !isExcluded(path)); } /** * @param classFile The class file. * @return true if included false otherwise. */ public boolean isSpecificallyIncluded(String classFile) { if (includes == null || includes.isEmpty()) { return false; } String path = normalizePath(classFile); return isIncluded(path); } private boolean isIncluded(String classFile) { if (includes == null || includes.isEmpty()) { return true; } return matchPaths(includes, classFile); } private boolean isExcluded(String classFile) { if (excludes == null || excludes.isEmpty()) { return false; } return matchPaths(excludes, classFile); } private boolean matchPaths(Set patterns, String classFile) { for (String pattern : patterns) { if (SelectorUtils.matchPath(pattern, classFile)) { return true; } } return false; } private String normalizePath(String path) { return (path != null) ? path.replace(File.separatorChar == '/' ? '\\' : '/', File.separatorChar) : null; } private Set normalizePatterns(Set patterns) { Set result = new HashSet<>(); if (patterns != null) { for (String pattern : patterns) { pattern = normalizePath(pattern); if (pattern.endsWith(File.separator)) { pattern += "**"; } result.add(pattern); } } return result; } /** {@inheritDoc} */ @Override public void finished() {} } ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/mojo/ArchiveFilter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.mojo; import java.util.Set; /** * @author David Blevins */ public class ArchiveFilter { private String artifact; private Set includes; private Set excludes; private boolean excludeDefaults = true; public String getArtifact() { return artifact; } public Set getIncludes() { return includes; } public Set getExcludes() { return excludes; } public boolean getExcludeDefaults() { return excludeDefaults; } } ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/mojo/ArtifactId.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.mojo; import org.apache.maven.artifact.Artifact; import org.apache.maven.model.Dependency; import org.codehaus.plexus.util.SelectorUtils; /** * @author Benjamin Bentmann */ class ArtifactId { private final String groupId; private final String artifactId; private final String type; private final String classifier; ArtifactId(Dependency dependency) { this(dependency.getGroupId(), dependency.getArtifactId(), dependency.getType(), dependency.getClassifier()); } ArtifactId(Artifact artifact) { this(artifact.getGroupId(), artifact.getArtifactId(), artifact.getType(), artifact.getClassifier()); } ArtifactId(String groupId, String artifactId, String type, String classifier) { this.groupId = (groupId != null) ? groupId : ""; this.artifactId = (artifactId != null) ? artifactId : ""; this.type = (type != null) ? type : ""; this.classifier = (classifier != null) ? classifier : ""; } ArtifactId(String id) { String[] tokens = new String[0]; if (id != null && id.length() > 0) { tokens = id.split(":", -1); } groupId = (tokens.length > 0) ? tokens[0] : ""; artifactId = (tokens.length > 1) ? tokens[1] : "*"; type = (tokens.length > 3) ? tokens[2] : "*"; classifier = (tokens.length > 3) ? tokens[3] : ((tokens.length > 2) ? tokens[2] : "*"); } public String getGroupId() { return groupId; } public String getArtifactId() { return artifactId; } public String getType() { return type; } public String getClassifier() { return classifier; } public boolean matches(ArtifactId pattern) { if (pattern == null) { return false; } if (!match(getGroupId(), pattern.getGroupId())) { return false; } if (!match(getArtifactId(), pattern.getArtifactId())) { return false; } if (!match(getType(), pattern.getType())) { return false; } return match(getClassifier(), pattern.getClassifier()); } private boolean match(String str, String pattern) { return SelectorUtils.match(pattern, str); } } ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/mojo/ArtifactSelector.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.mojo; import java.util.Collection; import java.util.HashSet; import org.apache.maven.artifact.Artifact; /** * @author Benjamin Bentmann */ class ArtifactSelector { private Collection includes; private Collection excludes; ArtifactSelector(Artifact projectArtifact, ArtifactSet artifactSet, String groupPrefix) { this( (artifactSet != null) ? artifactSet.getIncludes() : null, (artifactSet != null) ? artifactSet.getExcludes() : null, groupPrefix); if (projectArtifact != null && !this.includes.isEmpty()) { this.includes.add(new ArtifactId(projectArtifact)); } } ArtifactSelector(Collection includes, Collection excludes, String groupPrefix) { this.includes = toIds(includes); this.excludes = toIds(excludes); if (groupPrefix != null && groupPrefix.length() > 0) { this.includes.add(new ArtifactId(groupPrefix + "*", "*", "*", "*")); } } private static Collection toIds(Collection patterns) { Collection result = new HashSet<>(); if (patterns != null) { for (String pattern : patterns) { result.add(new ArtifactId(pattern)); } } return result; } public boolean isSelected(Artifact artifact) { return artifact != null && isSelected(new ArtifactId(artifact)); } boolean isSelected(ArtifactId id) { return (includes.isEmpty() || matches(includes, id)) && !matches(excludes, id); } private boolean matches(Collection patterns, ArtifactId id) { for (ArtifactId pattern : patterns) { if (id.matches(pattern)) { return true; } } return false; } } ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/mojo/ArtifactSet.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.mojo; import java.util.Set; /** * @author Jason van Zyl */ public class ArtifactSet { private Set includes; private Set excludes; public Set getIncludes() { return includes; } public Set getExcludes() { return excludes; } } ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/mojo/PackageRelocation.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.mojo; import java.util.List; /** * @author Jason van Zyl * @author Mauro Talevi */ public class PackageRelocation { private String pattern; private String shadedPattern; private List includes; private List excludes; private boolean rawString; private boolean shadeSerializedLambda; public String getPattern() { return pattern; } public String getShadedPattern() { return shadedPattern; } public List getIncludes() { return includes; } public List getExcludes() { return excludes; } public boolean isRawString() { return rawString; } public boolean isShadeSerializedLambda() { return shadeSerializedLambda; } } ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/mojo/RelativizePath.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.mojo; import java.io.File; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * */ public final class RelativizePath { private RelativizePath() { // } /** * relativize a pathname. * @param thing Absolute File of something. (e.g., a parent pom) * @param relativeTo base to relativize it do. (e.g., a pom into which a relative pathname to the 'thing' is to be * installed). * @return */ static String convertToRelativePath(File thing, File relativeTo) { StringBuilder relativePath; if (thing.getParentFile().equals(relativeTo.getParentFile())) { return thing.getName(); // a very simple relative path. } List thingDirectories = RelativizePath.parentDirs(thing); List relativeToDirectories = RelativizePath.parentDirs(relativeTo); // Get the shortest of the two paths int length = Math.min(thingDirectories.size(), relativeToDirectories.size()); int lastCommonRoot = -1; // index of the lowest directory down from the root that the two have in common. int index; // Find common root for (index = 0; index < length; index++) { if (thingDirectories.get(index).equals(relativeToDirectories.get(index))) { lastCommonRoot = index; } else { break; } } if (lastCommonRoot != -1) { // possible on Windows or other multi-root cases. // Build up the relative path relativePath = new StringBuilder(); // add ..'s to get from the base up to the common point for (index = lastCommonRoot + 1; index < relativeToDirectories.size(); index++) { relativePath.append("../"); } // now add down from the common point to the actual 'thing' item. for (index = lastCommonRoot + 1; index < thingDirectories.size(); index++) { relativePath.append(thingDirectories.get(index)).append('/'); } relativePath.append(thing.getName()); return relativePath.toString(); } return null; } static List parentDirs(File of) { List results = new ArrayList<>(); for (File p = of.getParentFile(); p != null; p = p.getParentFile()) { if (!"".equals(p.getName())) { results.add(p.getName()); } } Collections.reverse(results); return results; } } ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/mojo/ShadeMojo.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.mojo; import javax.inject.Inject; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.Writer; import java.nio.file.Files; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import org.apache.maven.RepositoryUtils; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.DefaultArtifact; import org.apache.maven.artifact.versioning.VersionRange; import org.apache.maven.execution.MavenSession; import org.apache.maven.model.Dependency; import org.apache.maven.model.Exclusion; import org.apache.maven.model.Model; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; import org.apache.maven.plugins.shade.ShadeRequest; import org.apache.maven.plugins.shade.Shader; import org.apache.maven.plugins.shade.filter.Filter; import org.apache.maven.plugins.shade.filter.MinijarFilter; import org.apache.maven.plugins.shade.filter.SimpleFilter; import org.apache.maven.plugins.shade.pom.PomWriter; import org.apache.maven.plugins.shade.relocation.Relocator; import org.apache.maven.plugins.shade.relocation.SerializedLambdaRelocator; import org.apache.maven.plugins.shade.relocation.SimpleRelocator; import org.apache.maven.plugins.shade.resource.ManifestResourceTransformer; import org.apache.maven.plugins.shade.resource.ResourceTransformer; import org.apache.maven.project.DefaultProjectBuildingRequest; import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProjectHelper; import org.apache.maven.project.ProjectBuilder; import org.apache.maven.project.ProjectBuildingException; import org.apache.maven.project.ProjectBuildingRequest; import org.apache.maven.project.ProjectBuildingResult; import org.codehaus.plexus.util.IOUtil; import org.codehaus.plexus.util.WriterFactory; import org.eclipse.aether.RepositorySystem; import org.eclipse.aether.collection.CollectRequest; import org.eclipse.aether.collection.CollectResult; import org.eclipse.aether.collection.DependencyCollectionException; import org.eclipse.aether.graph.DependencyNode; import org.eclipse.aether.resolution.ArtifactRequest; import org.eclipse.aether.resolution.ArtifactResolutionException; import static org.apache.maven.plugins.shade.resource.UseDependencyReducedPom.createPomReplaceTransformers; /** * Creates a shaded JAR artifact (i.e. embeds additional artifacts and optionally relocates their packages). * The generated shaded JAR becomes either the primary artifact or a secondary artifact of the current project. * The actual shading process is delegated to a {@link Shader} component. * It supports relocating references in binary classes and optionally also in Java source files, as well as resource transformations. * @see org.apache.maven.plugins.shade.DefaultShader DefaultShader (the default implementation of the Shader component). * @see Resource Transformers * * @author Jason van Zyl * @author Mauro Talevi * @author David Blevins * @author Hiram Chirino */ // CHECKSTYLE_OFF: LineLength @Mojo( name = "shade", defaultPhase = LifecyclePhase.PACKAGE, threadSafe = true, requiresDependencyResolution = ResolutionScope.RUNTIME) // CHECKSTYLE_ON: LineLength public class ShadeMojo extends AbstractMojo { /** * The current Maven session. */ @Parameter(defaultValue = "${session}", readonly = true, required = true) private MavenSession session; /** * The current Maven project. */ @Parameter(defaultValue = "${project}", readonly = true, required = true) private MavenProject project; /** * Artifacts to include/exclude from the final artifact. Artifacts are denoted by composite identifiers of the * general form groupId:artifactId:type:classifier. Since version 1.3, the wildcard characters '*' and * '?' can be used within the sub parts of those composite identifiers to do pattern matching. For convenience, the * syntax groupId is equivalent to groupId:*:*:*, groupId:artifactId is * equivalent to groupId:artifactId:*:* and groupId:artifactId:classifier is equivalent to * groupId:artifactId:*:classifier. For example: * *
     * <artifactSet>
     *   <includes>
     *     <include>org.apache.maven:*</include>
     *   </includes>
     *   <excludes>
     *     <exclude>*:maven-core</exclude>
     *   </excludes>
     * </artifactSet>
     * 
*/ @Parameter private ArtifactSet artifactSet; /** * Packages to be relocated. For example: * *
     * <relocations>
     *   <relocation>
     *     <pattern>org.apache</pattern>
     *     <shadedPattern>hidden.org.apache</shadedPattern>
     *     <includes>
     *       <include>org.apache.maven.*</include>
     *     </includes>
     *     <excludes>
     *       <exclude>org.apache.maven.Public*</exclude>
     *     </excludes>
     *   </relocation>
     *   <relocation>
     *     <pattern>Lorg/aspectj/</pattern>
     *     <shadedPattern>Lorg/example/shaded/aspectj/</shadedPattern>
     *     <rawString>true</rawString>
     *   </relocation>
     * </relocations>
     * 
* * Each {@code relocation} item must contain a non-empty {@code pattern} element. Its value may use either {@code /} or {@code .} as separator. It will be normalized accordingly depending on the relocation context (filesystem or fully qualified class/package name). * The {@code shadedPattern} element is optional, if not given or empty the shaded pattern will be the same as the pattern prefixed by {@code hidden.}. Its value may use either {@code /} or {@code .} as separator. It will be normalized accordingly depending on the relocation context (filesystem or fully qualified class/package name). * When {@code rawString} is set to {@code true} the given pattern is treated as regular expression {@link Pattern} otherwise is treated as plain String (not supporting any wildcards). * The {@code includes} and {@code excludes} elements are optional and can be used to further fine-tune the set of classes to be relocated. * Both are Ant-based patterns, i.e. support wildcards {@code *}, {@code **} and {@code ?}. * If both {@code includes} and {@code excludes} are given both conditions need to be fulfilled for a relocation to happen (i.e. both included and not excluded). * @see Class Relocation */ @SuppressWarnings("MismatchedReadAndWriteOfArray") @Parameter private PackageRelocation[] relocations; /** * Resource transformers to be used. * @see Resource Transformers */ @Parameter private ResourceTransformer[] transformers; /** * Archive Filters to be used. Allows you to specify an artifact in the form of a composite identifier as used by * {@link #artifactSet} and a set of include/exclude file patterns for filtering which contents of the archive are * added to the shaded jar. From a logical perspective, includes are processed before excludes, thus it's possible * 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: * *
     * <filters>
     *   <filter>
     *     <artifact>junit:junit</artifact>
     *     <includes>
     *       <include>org/junit/**</include>
     *     </includes>
     *     <excludes>
     *       <exclude>org/junit/experimental/**</exclude>
     *     </excludes>
     *   </filter>
     * </filters>
     * 
*/ @SuppressWarnings("MismatchedReadAndWriteOfArray") @Parameter private ArchiveFilter[] filters; /** * The destination directory for the shaded artifact. */ @Parameter(defaultValue = "${project.build.directory}") private File outputDirectory; /** * The name of the shaded artifactId. *

* If you like to change the name of the native artifact, you may use the <build><finalName> setting. If this * is set to something different than <build><finalName>, no file replacement will be performed, even if * shadedArtifactAttached is being used. */ @Parameter private String finalName; /** * The name of the shaded artifactId. So you may want to use a different artifactId and keep the standard version. * If the original artifactId was "foo" then the final artifact would be something like foo-1.0.jar. So if you * change the artifactId you might have something like foo-special-1.0.jar. */ @Parameter(defaultValue = "${project.artifactId}") private String shadedArtifactId; /** * If specified, this will include only artifacts which have groupIds which start with this. */ @Parameter private String shadedGroupFilter; /** * Defines whether the shaded artifact should be attached as classifier to the original artifact. If false, the * shaded jar will be the main artifact of the project */ @Parameter private boolean shadedArtifactAttached; /** * Flag whether to generate a simplified POM for the shaded artifact. If set to true, dependencies that * have been included into the uber JAR will be removed from the <dependencies> section of the * generated POM. The reduced POM will be named dependency-reduced-pom.xml and is stored into the same * directory as the shaded artifact. Unless you also specify dependencyReducedPomLocation, the plugin will create a * temporary file named dependency-reduced-pom.xml in the project basedir. */ @Parameter(defaultValue = "true") private boolean createDependencyReducedPom; /** * Where to put the dependency reduced pom. Note: setting a value for this parameter with a directory other than * ${basedir} will change the value of ${basedir} for all executions that come after the shade execution. This is * often not what you want. This is considered an open issue with this plugin. * * @since 1.7 */ @Parameter(defaultValue = "${basedir}/dependency-reduced-pom.xml") private File dependencyReducedPomLocation; /** * Create a dependency-reduced POM in ${basedir}/drp-UNIQUE.pom. This avoids build collisions of parallel builds * without moving the dependency-reduced POM to a different directory. The property * maven.shade.dependency-reduced-pom is set to the generated filename. * * @since 1.7.2 */ @Parameter(defaultValue = "false") private boolean generateUniqueDependencyReducedPom; /** * Add dependency reduced POM to the JAR instead of the original one provided by the project. * If {@code createDependencyReducedPom} is {@code false} this parameter will be ignored. * * @since 3.3.0 */ @Parameter(defaultValue = "false") private boolean useDependencyReducedPomInJar; /** * When true, dependencies are kept in the pom but with scope 'provided'; when false, the dependency is removed. */ @Parameter private boolean keepDependenciesWithProvidedScope; /** * When true, transitive deps of removed dependencies are promoted to direct dependencies. This should allow the * drop in replacement of the removed deps with the new shaded jar and everything should still work. */ @Parameter private boolean promoteTransitiveDependencies; /** * The name of the classifier used in case the shaded artifact is attached. */ @Parameter(defaultValue = "shaded") private String shadedClassifierName; /** * When true, it will attempt to create a sources jar as well */ @Parameter private boolean createSourcesJar; /** * When true, it will attempt to create a test sources jar. */ @Parameter private boolean createTestSourcesJar; /** * When true, it will attempt to shade the contents of Java source files when creating the sources JAR. When false, * it will just relocate the Java source files to the shaded paths, but will not modify the actual source file * contents. *

* Please note: This feature uses a heuristic search & replace approach which covers many, but definitely not * all possible cases of source code shading and its excludes. There is no full Java parser behind this * functionality, which would be the only way to get this right for Java language elements. As for matching within * Java string constants, this is next to impossible to get 100% right, trying to guess if they are used in * reflection or not. *

* Please understand that the source shading feature is not meant as a source code generator anyway, merely as a * tool creating reasonably plausible source code when navigating to a relocated library class from an IDE, * hopefully displaying source code which makes 95% sense - no more, no less. */ @Parameter(property = "shadeSourcesContent", defaultValue = "false") private boolean shadeSourcesContent; /** * When true, dependencies will be stripped down on the class level to only the transitive hull required for the * artifact. See also {@link #entryPoints}, if you wish to further optimize JAR minimization. *

* Note: This feature uses * jdependency. Its accuracy therefore 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. *

* Note: This feature requires Java 1.8 or higher due to its use of * jdependency. Its accuracy therefore also depends on * jdependency's limitations. *

* Configuration example: *

{@code
     * true
     * 
     *   org.acme.Application
     *   org.acme.OtherEntryPoint
     * 
     * }
* * @since 3.5.0 */ @Parameter private Set 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 * {@link #finalName}, {@link #shadedArtifactAttached}, {@link #shadedClassifierName} and * {@link #createDependencyReducedPom} to be ignored when used. * * @since 1.3 */ @Parameter private File outputFile; /** * You can pass here the roleHint about your own Shader implementation plexus component. * * @since 1.6 */ @Parameter private String shaderHint; /** * When true, the version of each dependency of the reduced pom will be based on the baseVersion of the original * dependency instead of its resolved version. For example, if the original pom (transitively) depends on * a:a:2.7-SNAPSHOT, if useBaseVersion is set to false, the reduced pom will depend on a:a:2.7-20130312.222222-12 * whereas if useBaseVersion is set to true, the reduced pom will depend on a:a:2.7-SNAPSHOT * * @since 3.0 */ @Parameter(defaultValue = "false") private boolean useBaseVersion; /** * When true, creates a shaded test-jar artifact as well. */ @Parameter(defaultValue = "false") private boolean shadeTestJar; /** * When true, skips the execution of this MOJO. * @since 3.3.0 */ @Parameter(defaultValue = "false") private boolean skip; /** * Extra JAR files to infuse into shaded result. Accepts list of files that must exists. If any of specified * files does not exist (or is not a file), Mojo will fail. *

* Extra JARs will be processed in same way as main JAR (if any) is: applied relocation, resource transformers * but not filtering. *

* Note: this feature should be used lightly, is not meant as ability to replace dependency hull! It is more * just a feature to be able to slightly "differentiate" shaded JAR from main only. * * @since 3.6.0 */ @Parameter private List extraJars; /** * Extra Artifacts to infuse into shaded result. Accepts list of GAVs in form of * {@code :[:[:]]:} that will be resolved. If any of them * cannot be resolved, Mojo will fail. *

* The artifacts will be resolved (not transitively), and will be processed in same way as dependency JARs * are (if any): applied relocation, resource transformers and filtering. *

* Note: this feature should be used lightly, is not meant as ability to replace dependency hull! It is more * just a feature to be able to slightly "differentiate" shaded JAR from main only. * * @since 3.6.0 */ @Parameter private List extraArtifacts; @Inject private MavenProjectHelper projectHelper; @Inject private Shader shader; @Inject private RepositorySystem repositorySystem; /** * ProjectBuilder, needed to create projects from the artifacts. */ @Inject private ProjectBuilder projectBuilder; /** * All the present Shaders. */ @Inject private Map shaders; /** * @throws MojoExecutionException in case of an error. */ @SuppressWarnings("checkstyle:methodlength") @Override public void execute() throws MojoExecutionException { if (skip) { getLog().info("Shading has been skipped."); return; } setupHintedShader(); Set artifacts = new LinkedHashSet<>(); Set artifactIds = new LinkedHashSet<>(); Set sourceArtifacts = new LinkedHashSet<>(); Set testArtifacts = new LinkedHashSet<>(); Set testSourceArtifacts = new LinkedHashSet<>(); ArtifactSelector artifactSelector = new ArtifactSelector(project.getArtifact(), artifactSet, shadedGroupFilter); if (artifactSelector.isSelected(project.getArtifact()) && !"pom".equals(project.getArtifact().getType())) { if (invalidMainArtifact()) { createErrorOutput(); throw new MojoExecutionException( "Failed to create shaded artifact, " + "project main artifact does not exist."); } artifacts.add(project.getArtifact().getFile()); if (extraJars != null && !extraJars.isEmpty()) { for (File extraJar : extraJars) { if (!Files.isRegularFile(extraJar.toPath())) { throw new MojoExecutionException( "Failed to create shaded artifact: parameter extraJars contains path " + extraJar + " that is not a file (does not exist or is not a file)"); } artifacts.add(extraJar); } } if (createSourcesJar) { File file = shadedSourcesArtifactFile(); if (file.isFile()) { sourceArtifacts.add(file); } } if (shadeTestJar) { File file = shadedTestArtifactFile(); if (file.isFile()) { testArtifacts.add(file); } } if (createTestSourcesJar) { File file = shadedTestSourcesArtifactFile(); if (file.isFile()) { testSourceArtifacts.add(file); } } } List processedArtifacts = processArtifactSelectors( artifacts, artifactIds, sourceArtifacts, testArtifacts, testSourceArtifacts, artifactSelector); File outputJar = (outputFile != null) ? outputFile : shadedArtifactFileWithClassifier(); File sourcesJar = shadedSourceArtifactFileWithClassifier(); File testJar = shadedTestArtifactFileWithClassifier(); File testSourcesJar = shadedTestSourceArtifactFileWithClassifier(); // Now add our extra resources try { List filters = getFilters(processedArtifacts); List relocators = getRelocators(); List resourceTransformers = getResourceTransformers(); if (createDependencyReducedPom) { createDependencyReducedPom(artifactIds); if (useDependencyReducedPomInJar) { // In some cases the used implementation of the resourceTransformers is immutable. resourceTransformers = new ArrayList<>(resourceTransformers); resourceTransformers.addAll(createPomReplaceTransformers(project, dependencyReducedPomLocation)); } } ShadeRequest shadeRequest = shadeRequest("jar", artifacts, outputJar, filters, relocators, resourceTransformers); shader.shade(shadeRequest); if (createSourcesJar) { ShadeRequest shadeSourcesRequest = createShadeSourcesRequest( "sources-jar", sourceArtifacts, sourcesJar, filters, relocators, resourceTransformers); shader.shade(shadeSourcesRequest); } if (shadeTestJar) { ShadeRequest shadeTestRequest = shadeRequest("test-jar", testArtifacts, testJar, filters, relocators, resourceTransformers); shader.shade(shadeTestRequest); } if (createTestSourcesJar) { ShadeRequest shadeTestSourcesRequest = createShadeSourcesRequest( "test-sources-jar", testSourceArtifacts, testSourcesJar, filters, relocators, resourceTransformers); shader.shade(shadeTestSourcesRequest); } if (outputFile == null) { boolean renamed = false; // rename the output file if a specific finalName is set // but don't rename if the finalName is the // because this will be handled implicitly later if (finalName != null && finalName.length() > 0 // && !finalName.equals(project.getBuild().getFinalName())) { String finalFileName = finalName + "." + project.getArtifact().getArtifactHandler().getExtension(); File finalFile = new File(outputDirectory, finalFileName); replaceFile(finalFile, outputJar); outputJar = finalFile; // Also support the sources JAR if (createSourcesJar) { finalFileName = finalName + "-sources.jar"; finalFile = new File(outputDirectory, finalFileName); replaceFile(finalFile, sourcesJar); sourcesJar = finalFile; } // Also support the test JAR if (shadeTestJar) { finalFileName = finalName + "-tests.jar"; finalFile = new File(outputDirectory, finalFileName); replaceFile(finalFile, testJar); testJar = finalFile; } if (createTestSourcesJar) { finalFileName = finalName + "-test-sources.jar"; finalFile = new File(outputDirectory, finalFileName); replaceFile(finalFile, testSourcesJar); testSourcesJar = finalFile; } renamed = true; } if (shadedArtifactAttached) { getLog().info("Attaching shaded artifact."); projectHelper.attachArtifact( project, project.getArtifact().getType(), shadedClassifierName, outputJar); if (createSourcesJar) { projectHelper.attachArtifact( project, "java-source", shadedClassifierName + "-sources", sourcesJar); } if (shadeTestJar) { projectHelper.attachArtifact(project, "test-jar", shadedClassifierName + "-tests", testJar); } if (createTestSourcesJar) { projectHelper.attachArtifact( project, "java-source", shadedClassifierName + "-test-sources", testSourcesJar); } } else if (!renamed) { getLog().info("Replacing original artifact with shaded artifact."); File originalArtifact = project.getArtifact().getFile(); if (originalArtifact != null) { replaceFile(originalArtifact, outputJar); if (createSourcesJar) { getLog().info("Replacing original source artifact with shaded source artifact."); File shadedSources = shadedSourcesArtifactFile(); replaceFile(shadedSources, sourcesJar); projectHelper.attachArtifact(project, "java-source", "sources", shadedSources); } if (shadeTestJar) { getLog().info("Replacing original test artifact with shaded test artifact."); File shadedTests = shadedTestArtifactFile(); replaceFile(shadedTests, testJar); projectHelper.attachArtifact(project, "test-jar", shadedTests); } if (createTestSourcesJar) { getLog().info("Replacing original test source artifact " + "with shaded test source artifact."); File shadedTestSources = shadedTestSourcesArtifactFile(); replaceFile(shadedTestSources, testSourcesJar); projectHelper.attachArtifact(project, "java-source", "test-sources", shadedTestSources); } } } } } catch (Exception e) { throw new MojoExecutionException("Error creating shaded jar: " + e.getMessage(), e); } } private void createErrorOutput() { getLog().error("The project main artifact does not exist. This could have the following"); getLog().error("reasons:"); getLog().error("- You have invoked the goal directly from the command line. This is not"); getLog().error(" supported. Please add the goal to the default lifecycle via an"); getLog().error(" element in your POM and use \"mvn package\" to have it run."); getLog().error("- You have bound the goal to a lifecycle phase before \"package\". Please"); getLog().error(" remove this binding from your POM such that the goal will be run in"); getLog().error(" the proper phase."); getLog().error("- You removed the configuration of the maven-jar-plugin that produces the main artifact."); } private ShadeRequest shadeRequest( String shade, Set artifacts, File outputJar, List filters, List relocators, List resourceTransformers) { ShadeRequest shadeRequest = new ShadeRequest(); shadeRequest.setJars(artifacts); shadeRequest.setUberJar(outputJar); shadeRequest.setFilters(filters); shadeRequest.setRelocators(relocators); shadeRequest.setResourceTransformers(toResourceTransformers(shade, resourceTransformers)); return shadeRequest; } private ShadeRequest createShadeSourcesRequest( String shade, Set testArtifacts, File testJar, List filters, List relocators, List resourceTransformers) { ShadeRequest shadeSourcesRequest = shadeRequest(shade, testArtifacts, testJar, filters, relocators, resourceTransformers); shadeSourcesRequest.setShadeSourcesContent(shadeSourcesContent); return shadeSourcesRequest; } private void setupHintedShader() throws MojoExecutionException { if (shaderHint != null) { shader = shaders.get(shaderHint); if (shader == null) { throw new MojoExecutionException( "unable to lookup own Shader implementation with hint: '" + shaderHint + "'"); } } } private List processArtifactSelectors( Set artifacts, Set artifactIds, Set sourceArtifacts, Set testArtifacts, Set testSourceArtifacts, ArtifactSelector artifactSelector) throws MojoExecutionException { List excludedArtifacts = new ArrayList<>(); List pomArtifacts = new ArrayList<>(); List emptySourceArtifacts = new ArrayList<>(); List emptyTestArtifacts = new ArrayList<>(); List emptyTestSourceArtifacts = new ArrayList<>(); ArrayList processedArtifacts = new ArrayList<>(); if (extraArtifacts != null && !extraArtifacts.isEmpty()) { processedArtifacts.addAll(extraArtifacts.stream() .map(org.eclipse.aether.artifact.DefaultArtifact::new) .map(RepositoryUtils::toArtifact) .collect(Collectors.toList())); for (Artifact artifact : processedArtifacts) { try { org.eclipse.aether.artifact.Artifact resolved = resolveArtifact(RepositoryUtils.toArtifact(artifact)); if (resolved.getFile() != null) { artifact.setFile(resolved.getFile()); } } catch (ArtifactResolutionException e) { throw new MojoExecutionException( "Failed to create shaded artifact: parameter extraArtifacts contains artifact " + artifact.getId() + " that is not resolvable", e); } } } processedArtifacts.addAll(project.getArtifacts()); // for loop over COPY; as we add to the list in this loop for (Artifact artifact : new ArrayList<>(processedArtifacts)) { if (!artifactSelector.isSelected(artifact)) { excludedArtifacts.add(artifact); continue; } if ("pom".equals(artifact.getType())) { pomArtifacts.add(artifact); continue; } getLog().debug("Including " + artifact.getId() + " in the shaded jar."); artifacts.add(artifact.getFile()); artifactIds.add(getId(artifact)); if (createSourcesJar) { Artifact sources = resolveArtifactForClassifier(artifact, "sources"); if (sources != null) { if (sources.getFile().length() > 0) { sourceArtifacts.add(sources.getFile()); processedArtifacts.add(sources); } else { emptySourceArtifacts.add(artifact); } } } if (shadeTestJar) { Artifact tests = resolveArtifactForClassifier(artifact, "tests"); if (tests != null) { if (tests.getFile().length() > 0) { testArtifacts.add(tests.getFile()); processedArtifacts.add(tests); } else { emptyTestArtifacts.add(artifact); } } } if (createTestSourcesJar) { Artifact testSources = resolveArtifactForClassifier(artifact, "test-sources"); if (testSources != null) { testSourceArtifacts.add(testSources.getFile()); processedArtifacts.add(testSources); } else { emptyTestSourceArtifacts.add(artifact); } } } processedArtifacts.removeAll(excludedArtifacts); processedArtifacts.removeAll(pomArtifacts); processedArtifacts.removeAll(emptySourceArtifacts); processedArtifacts.removeAll(emptyTestArtifacts); processedArtifacts.removeAll(emptyTestSourceArtifacts); for (Artifact artifact : excludedArtifacts) { getLog().debug("Excluding " + artifact.getId() + " from the shaded jar."); } for (Artifact artifact : pomArtifacts) { getLog().debug("Skipping pom dependency " + artifact.getId() + " in the shaded jar."); } for (Artifact artifact : emptySourceArtifacts) { getLog().warn("Skipping empty source jar " + artifact.getId() + "."); } for (Artifact artifact : emptyTestArtifacts) { getLog().warn("Skipping empty test jar " + artifact.getId() + "."); } for (Artifact artifact : emptyTestSourceArtifacts) { getLog().warn("Skipping empty test source jar " + artifact.getId() + "."); } return processedArtifacts; } private boolean invalidMainArtifact() { return project.getArtifact().getFile() == null || !project.getArtifact().getFile().isFile(); } private void replaceFile(File oldFile, File newFile) throws MojoExecutionException { getLog().debug("Replacing " + oldFile + " with " + newFile); File origFile = new File(outputDirectory, "original-" + oldFile.getName()); if (oldFile.exists() && !oldFile.renameTo(origFile)) { // try a gc to see if an unclosed stream needs garbage collecting System.gc(); System.gc(); if (!oldFile.renameTo(origFile)) { // Still didn't work. We'll do a copy try { copyFiles(oldFile, origFile); } catch (IOException ex) { // kind of ignorable here. We're just trying to save the original getLog().warn(ex); } } } if (!newFile.renameTo(oldFile)) { // try a gc to see if an unclosed stream needs garbage collecting System.gc(); System.gc(); if (!newFile.renameTo(oldFile)) { // Still didn't work. We'll do a copy try { copyFiles(newFile, oldFile); } catch (IOException ex) { throw new MojoExecutionException("Could not replace original artifact with shaded artifact!", ex); } } } } private void copyFiles(File source, File target) throws IOException { try (InputStream in = Files.newInputStream(source.toPath()); OutputStream out = Files.newOutputStream(target.toPath())) { IOUtil.copy(in, out); } } private Artifact resolveArtifactForClassifier(Artifact artifact, String classifier) { Artifact toResolve = new DefaultArtifact( artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersionRange() == null ? VersionRange.createFromVersion(artifact.getVersion()) : artifact.getVersionRange(), artifact.getScope(), artifact.getType(), classifier, artifact.getArtifactHandler(), artifact.isOptional()); try { org.eclipse.aether.artifact.Artifact resolved = resolveArtifact(RepositoryUtils.toArtifact(toResolve)); if (resolved.getFile() != null) { toResolve.setFile(resolved.getFile()); return toResolve; } return null; } catch (ArtifactResolutionException e) { getLog().warn("Could not get " + classifier + " for " + artifact); return null; } } private org.eclipse.aether.artifact.Artifact resolveArtifact(org.eclipse.aether.artifact.Artifact artifact) throws ArtifactResolutionException { return repositorySystem .resolveArtifact( session.getRepositorySession(), new ArtifactRequest(artifact, project.getRemoteProjectRepositories(), "shade")) .getArtifact(); } private List getRelocators() { List relocators = new ArrayList<>(); if (relocations == null) { return relocators; } for (PackageRelocation r : relocations) { relocators.add(new SimpleRelocator( r.getPattern(), r.getShadedPattern(), r.getIncludes(), r.getExcludes(), r.isRawString())); if (r.isShadeSerializedLambda()) { relocators.add(new SerializedLambdaRelocator( r.getPattern(), r.getShadedPattern(), r.getIncludes(), r.getExcludes(), r.isRawString())); } } return relocators; } private List getResourceTransformers() throws MojoExecutionException { if (transformers == null) { return Collections.emptyList(); } for (ResourceTransformer transformer : transformers) { if (transformer == null) { throw new MojoExecutionException( "Failed to create shaded artifact: parameter transformers contains null (double-check XML attribute)"); } } return Arrays.asList(transformers); } private List getFilters(List artifactCollection) throws MojoExecutionException { List filters = new ArrayList<>(); List simpleFilters = new ArrayList<>(); if (this.filters != null && this.filters.length > 0) { Map artifacts = new HashMap<>(); // artifactCollection does not contain project; that must also be subjected to filtering artifacts.put(project.getArtifact(), new ArtifactId(project.getArtifact())); for (Artifact artifact : artifactCollection) { artifacts.put(artifact, new ArtifactId(artifact)); } for (ArchiveFilter filter : this.filters) { ArtifactId pattern = new ArtifactId(filter.getArtifact()); Set jars = new HashSet<>(); for (Map.Entry entry : artifacts.entrySet()) { if (entry.getValue().matches(pattern)) { Artifact artifact = entry.getKey(); jars.add(artifact.getFile()); if (createSourcesJar) { Artifact sources = resolveArtifactForClassifier(artifact, "sources"); if (sources != null) { jars.add(sources.getFile()); } } if (shadeTestJar) { Artifact tests = resolveArtifactForClassifier(artifact, "tests"); if (tests != null) { jars.add(tests.getFile()); } } } } if (jars.isEmpty()) { getLog().debug("No artifact matching filter " + filter.getArtifact()); continue; } simpleFilters.add(new SimpleFilter(jars, filter)); } } filters.addAll(simpleFilters); if (minimizeJar) { 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, entryPoints)); } catch (IOException e) { throw new MojoExecutionException("Failed to analyze class dependencies", e); } } return filters; } private File shadedArtifactFileWithClassifier() { Artifact artifact = project.getArtifact(); final String shadedName = shadedArtifactId + "-" + artifact.getVersion() + "-" + shadedClassifierName + "." + artifact.getArtifactHandler().getExtension(); return new File(outputDirectory, shadedName); } private File shadedSourceArtifactFileWithClassifier() { return shadedArtifactFileWithClassifier("sources"); } private File shadedTestSourceArtifactFileWithClassifier() { return shadedArtifactFileWithClassifier("test-sources"); } private File shadedArtifactFileWithClassifier(String classifier) { Artifact artifact = project.getArtifact(); final String shadedName = shadedArtifactId + "-" + artifact.getVersion() + "-" + shadedClassifierName + "-" + classifier + "." + artifact.getArtifactHandler().getExtension(); return new File(outputDirectory, shadedName); } private File shadedTestArtifactFileWithClassifier() { return shadedArtifactFileWithClassifier("tests"); } private File shadedSourcesArtifactFile() { return shadedArtifactFile("sources"); } private File shadedTestSourcesArtifactFile() { return shadedArtifactFile("test-sources"); } private File shadedArtifactFile(String classifier) { Artifact artifact = project.getArtifact(); String shadedName; if (project.getBuild().getFinalName() != null) { shadedName = project.getBuild().getFinalName() + "-" + classifier + "." + artifact.getArtifactHandler().getExtension(); } else { shadedName = shadedArtifactId + "-" + artifact.getVersion() + "-" + classifier + "." + artifact.getArtifactHandler().getExtension(); } return new File(outputDirectory, shadedName); } private File shadedTestArtifactFile() { return shadedArtifactFile("tests"); } // We need to find the direct dependencies that have been included in the uber JAR so that we can modify the // POM accordingly. private void createDependencyReducedPom(Set artifactsToRemove) throws IOException, ProjectBuildingException, DependencyCollectionException { List transitiveDeps = new ArrayList<>(); // NOTE: By using the getArtifacts() we get the completely evaluated artifacts // including the system scoped artifacts with expanded values of properties used. for (Artifact artifact : project.getArtifacts()) { if ("pom".equals(artifact.getType())) { // don't include pom type dependencies in dependency reduced pom continue; } // promote Dependency dep = createDependency(artifact); // we'll figure out the exclusions in a bit. transitiveDeps.add(dep); } Model model = project.getOriginalModel(); // MSHADE-413: Must not use objects (for example `Model` or `Dependency`) that are "owned // by Maven" and being used by other projects/plugins. Modifying those will break the // correctness of the build - or cause an endless loop. List origDeps = new ArrayList<>(); List source = promoteTransitiveDependencies ? transitiveDeps : project.getDependencies(); for (Dependency d : source) { origDeps.add(d.clone()); } model = model.clone(); // MSHADE-185: We will remove all system scoped dependencies which usually // have some kind of property usage. At this time the properties within // such things are already evaluated. List originalDependencies = model.getDependencies(); removeSystemScopedDependencies(artifactsToRemove, originalDependencies); List dependencies = new ArrayList<>(); boolean modified = false; for (Dependency d : origDeps) { if (artifactsToRemove.contains(getId(d))) { if (keepDependenciesWithProvidedScope) { if (!"provided".equals(d.getScope())) { modified = true; d.setScope("provided"); } } else { modified = true; continue; } } dependencies.add(d); } // MSHADE-155 model.setArtifactId(shadedArtifactId); // MSHADE-185: We will add those system scoped dependencies // from the non interpolated original pom file. So we keep // things like this: ${tools.jar} intact. addSystemScopedDependencyFromNonInterpolatedPom(dependencies, originalDependencies); // Check to see if we have a reduction and if so rewrite the POM. rewriteDependencyReducedPomIfWeHaveReduction(dependencies, modified, transitiveDeps, model); } private void rewriteDependencyReducedPomIfWeHaveReduction( List dependencies, boolean modified, List transitiveDeps, Model model) throws IOException, ProjectBuildingException, DependencyCollectionException { if (modified) { for (int loopCounter = 0; modified; loopCounter++) { model.setDependencies(dependencies); if (generateUniqueDependencyReducedPom) { dependencyReducedPomLocation = Files.createTempFile( project.getBasedir().toPath(), "dependency-reduced-pom-", ".xml") .toFile(); project.getProperties() .setProperty( "maven.shade.dependency-reduced-pom", dependencyReducedPomLocation.getAbsolutePath()); } else { if (dependencyReducedPomLocation == null) { // MSHADE-123: We can't default to 'target' because it messes up uses of ${project.basedir} dependencyReducedPomLocation = new File(project.getBasedir(), "dependency-reduced-pom.xml"); } } File f = dependencyReducedPomLocation; // MSHADE-225 // Works for now, maybe there's a better algorithm where no for-loop is required if (loopCounter == 0) { getLog().info("Dependency-reduced POM written at: " + f.getAbsolutePath()); } if (f.exists()) { // noinspection ResultOfMethodCallIgnored f.delete(); } Writer w = WriterFactory.newXmlWriter(f); String replaceRelativePath = null; if (model.getParent() != null) { replaceRelativePath = model.getParent().getRelativePath(); } if (model.getParent() != null) { File parentFile = new File(project.getBasedir(), model.getParent().getRelativePath()).getCanonicalFile(); if (!parentFile.isFile()) { parentFile = new File(parentFile, "pom.xml"); } parentFile = parentFile.getCanonicalFile(); String relPath = RelativizePath.convertToRelativePath(parentFile, f); model.getParent().setRelativePath(relPath); } try { PomWriter.write(w, model, true); } finally { if (model.getParent() != null) { model.getParent().setRelativePath(replaceRelativePath); } w.close(); } synchronized (session.getProjectBuildingRequest()) { // Lock critical section to fix MSHADE-467 ProjectBuildingRequest projectBuildingRequest = new DefaultProjectBuildingRequest(session.getProjectBuildingRequest()); projectBuildingRequest.setLocalRepository(session.getLocalRepository()); projectBuildingRequest.setRemoteRepositories(project.getRemoteArtifactRepositories()); ProjectBuildingResult result = projectBuilder.build(f, projectBuildingRequest); getLog().debug("updateExcludesInDeps()"); modified = updateExcludesInDeps(result.getProject(), dependencies, transitiveDeps); } } project.setFile(dependencyReducedPomLocation); } } private void removeSystemScopedDependencies(Set artifactsToRemove, List originalDependencies) { for (Dependency dependency : originalDependencies) { if (dependency.getScope() != null && dependency.getScope().equalsIgnoreCase("system")) { artifactsToRemove.add(getId(dependency)); } } } private void addSystemScopedDependencyFromNonInterpolatedPom( List dependencies, List originalDependencies) { for (Dependency dependency : originalDependencies) { if (dependency.getScope() != null && dependency.getScope().equalsIgnoreCase("system")) { dependencies.add(dependency); } } } private Dependency createDependency(Artifact artifact) { Dependency dep = new Dependency(); dep.setArtifactId(artifact.getArtifactId()); if (artifact.hasClassifier()) { dep.setClassifier(artifact.getClassifier()); } dep.setGroupId(artifact.getGroupId()); dep.setOptional(artifact.isOptional()); dep.setScope(artifact.getScope()); dep.setType(artifact.getType()); if (useBaseVersion) { dep.setVersion(artifact.getBaseVersion()); } else { dep.setVersion(artifact.getVersion()); } return dep; } private String getId(Artifact artifact) { return getId(artifact.getGroupId(), artifact.getArtifactId(), artifact.getType(), artifact.getClassifier()); } private String getId(Dependency dependency) { return getId( dependency.getGroupId(), dependency.getArtifactId(), dependency.getType(), dependency.getClassifier()); } private String getId(String groupId, String artifactId, String type, String classifier) { return groupId + ":" + artifactId + ":" + type + ":" + ((classifier != null) ? classifier : ""); } public boolean updateExcludesInDeps( MavenProject project, List dependencies, List transitiveDeps) throws DependencyCollectionException { CollectRequest collectRequest = new CollectRequest(); collectRequest.setRootArtifact(RepositoryUtils.toArtifact(project.getArtifact())); collectRequest.setRepositories(project.getRemoteProjectRepositories()); collectRequest.setDependencies(project.getDependencies().stream() .map(d -> RepositoryUtils.toDependency( d, session.getRepositorySession().getArtifactTypeRegistry())) .collect(Collectors.toList())); if (project.getDependencyManagement() != null) { collectRequest.setManagedDependencies(project.getDependencyManagement().getDependencies().stream() .map(d -> RepositoryUtils.toDependency( d, session.getRepositorySession().getArtifactTypeRegistry())) .collect(Collectors.toList())); } CollectResult result = repositorySystem.collectDependencies(session.getRepositorySession(), collectRequest); boolean modified = false; if (result.getRoot() != null) { for (DependencyNode n2 : result.getRoot().getChildren()) { String artifactId2 = getId(RepositoryUtils.toArtifact(n2.getArtifact())); for (DependencyNode n3 : n2.getChildren()) { // stupid m-a Artifact that has no idea what it is: dependency or artifact? Artifact artifact3 = RepositoryUtils.toArtifact(n3.getArtifact()); artifact3.setScope(n3.getDependency().getScope()); String artifactId3 = getId(artifact3); // check if it really isn't in the list of original dependencies. Maven // prior to 2.0.8 may grab versions from transients instead of // from the direct deps in which case they would be marked included // instead of OMITTED_FOR_DUPLICATE // also, if not promoting the transitives, level 2's would be included boolean found = false; for (Dependency dep : transitiveDeps) { if (getId(dep).equals(artifactId3)) { found = true; break; } } // MSHADE-311: do not add exclusion for provided transitive dep // note: MSHADE-31 introduced the exclusion logic for promoteTransitiveDependencies=true, // but as of 3.2.1 promoteTransitiveDependencies has no effect for provided deps, // which makes this fix even possible (see also MSHADE-181) if (!found && !"provided".equals(artifact3.getScope())) { getLog().debug(String.format( "dependency %s (scope %s) not found in transitive dependencies", artifactId3, artifact3.getScope())); for (Dependency dep : dependencies) { if (getId(dep).equals(artifactId2)) { // MSHADE-413: First check whether the exclusion has already been added, // because it's meaningless to add it more than once. Certain cases // can end up adding the exclusion "forever" and cause an endless loop // rewriting the whole dependency-reduced-pom.xml file. if (!dependencyHasExclusion(dep, artifact3)) { getLog().debug(String.format( "Adding exclusion for dependency %s (scope %s) " + "to %s (scope %s)", artifactId3, artifact3.getScope(), getId(dep), dep.getScope())); Exclusion exclusion = new Exclusion(); exclusion.setArtifactId(artifact3.getArtifactId()); exclusion.setGroupId(artifact3.getGroupId()); dep.addExclusion(exclusion); modified = true; break; } } } } } } } return modified; } private boolean dependencyHasExclusion(Dependency dep, Artifact exclusionToCheck) { boolean containsExclusion = false; for (Exclusion existingExclusion : dep.getExclusions()) { if (existingExclusion.getGroupId().equals(exclusionToCheck.getGroupId()) && existingExclusion.getArtifactId().equals(exclusionToCheck.getArtifactId())) { containsExclusion = true; break; } } return containsExclusion; } private List toResourceTransformers( String shade, List resourceTransformers) { List forShade = new ArrayList<>(); ManifestResourceTransformer lastMt = null; for (ResourceTransformer transformer : resourceTransformers) { if (!(transformer instanceof ManifestResourceTransformer)) { forShade.add(transformer); } else if (((ManifestResourceTransformer) transformer).isForShade(shade)) { final ManifestResourceTransformer mt = (ManifestResourceTransformer) transformer; if (mt.isUsedForDefaultShading() && lastMt != null && !lastMt.isUsedForDefaultShading()) { continue; // skip, we already have a specific transformer } if (!mt.isUsedForDefaultShading() && lastMt != null && lastMt.isUsedForDefaultShading()) { forShade.remove(lastMt); } else if (!mt.isUsedForDefaultShading() && lastMt != null) { getLog().warn("Ambiguous manifest transformer definition for '" + shade + "': " + mt + " / " + lastMt); } if (lastMt == null || !mt.isUsedForDefaultShading()) { lastMt = mt; } forShade.add(transformer); } } return forShade; } } ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/pom/Counter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.pom; /** * Separate class for counter. */ public class Counter { // --------------------------/ // - Class/Member Variables -/ // --------------------------/ /** * Field currentIndex */ private int currentIndex = 0; /** * Field level */ private int level; // ----------------/ // - Constructors -/ // ----------------/ public Counter(int depthLevel) { level = depthLevel; } // -- org.apache.maven.model.io.jdom.Counter(int) // -----------/ // - Methods -/ // -----------/ /** * Method getCurrentIndex */ public int getCurrentIndex() { return currentIndex; } // -- int getCurrentIndex() /** * Method getDepth * @return {@link #level} */ public int getDepth() { return level; } // -- int getDepth() /** * Method increaseCount */ public void increaseCount() { currentIndex = currentIndex + 1; } // -- void increaseCount() } ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/pom/MavenJDOMWriter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.pom; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Objects; import org.apache.maven.model.ActivationFile; import org.apache.maven.model.ActivationOS; import org.apache.maven.model.ActivationProperty; import org.apache.maven.model.Build; import org.apache.maven.model.BuildBase; import org.apache.maven.model.CiManagement; import org.apache.maven.model.ConfigurationContainer; import org.apache.maven.model.Contributor; import org.apache.maven.model.Dependency; import org.apache.maven.model.DependencyManagement; import org.apache.maven.model.DeploymentRepository; import org.apache.maven.model.Developer; import org.apache.maven.model.DistributionManagement; import org.apache.maven.model.Exclusion; import org.apache.maven.model.Extension; import org.apache.maven.model.FileSet; import org.apache.maven.model.IssueManagement; import org.apache.maven.model.License; import org.apache.maven.model.MailingList; import org.apache.maven.model.Model; import org.apache.maven.model.ModelBase; import org.apache.maven.model.Notifier; import org.apache.maven.model.Organization; import org.apache.maven.model.Parent; import org.apache.maven.model.PatternSet; import org.apache.maven.model.Plugin; import org.apache.maven.model.PluginConfiguration; import org.apache.maven.model.PluginContainer; import org.apache.maven.model.PluginExecution; import org.apache.maven.model.PluginManagement; import org.apache.maven.model.Prerequisites; import org.apache.maven.model.Profile; import org.apache.maven.model.Relocation; import org.apache.maven.model.ReportPlugin; import org.apache.maven.model.ReportSet; import org.apache.maven.model.Reporting; import org.apache.maven.model.Repository; import org.apache.maven.model.RepositoryBase; import org.apache.maven.model.RepositoryPolicy; import org.apache.maven.model.Resource; import org.apache.maven.model.Scm; import org.apache.maven.model.Site; import org.codehaus.plexus.util.xml.Xpp3Dom; import org.jdom2.Content; import org.jdom2.DefaultJDOMFactory; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.Text; import org.jdom2.output.Format; import org.jdom2.output.XMLOutputter; /** * Class MavenJDOMWriter. * */ public class MavenJDOMWriter { /** * Field factory */ private final DefaultJDOMFactory factory; /** * Field lineSeparator */ private final String lineSeparator; public MavenJDOMWriter() { this("\n"); } public MavenJDOMWriter(final String lineSeparator) { this.factory = new DefaultJDOMFactory(); this.lineSeparator = Objects.requireNonNull(lineSeparator); } /** * Method findAndReplaceProperties * * @param counter {@link Counter} * @param props {@link Map} * @param name The name. * @param parent {@link Element} * @return {@link Element} */ protected Element findAndReplaceProperties(Counter counter, Element parent, String name, Map props) { Map properties = props; boolean shouldExist = properties != null && !properties.isEmpty(); Element element = updateElement(counter, parent, name, shouldExist); if (shouldExist) { Counter innerCounter = new Counter(counter.getDepth() + 1); for (Map.Entry entry : properties.entrySet()) { String key = entry.getKey(); findAndReplaceSimpleElement(innerCounter, element, key, entry.getValue(), null); } List lst = new ArrayList<>(properties.keySet()); Iterator it = element.getChildren().iterator(); while (it.hasNext()) { Element elem = it.next(); String key = elem.getName(); if (!lst.contains(key)) { it.remove(); } } } return element; } /** * Method findAndReplaceSimpleElement * * @param counter {@link Counter} * @param defaultValue The default value. * @param text The text. * @param name The name. * @param parent The parent. * @return {@link Element} */ protected Element findAndReplaceSimpleElement( Counter counter, Element parent, String name, String text, String defaultValue) { if (defaultValue != null && text != null && defaultValue.equals(text)) { Element element = parent.getChild(name, parent.getNamespace()); // if exist and is default value or if doesn't exist.. just keep the way it is.. if (element == null || defaultValue.equals(element.getText())) { return element; } } boolean shouldExist = text != null && text.trim().length() > 0; Element element = updateElement(counter, parent, name, shouldExist); if (shouldExist) { element.setText(text); } return element; } /** * Method findAndReplaceSimpleLists * * @param counter {@link Counter} * @param childName The childName * @param parentName The parentName * @param list The list of elements. * @param parent The parent. * @return {@link Element} */ protected Element findAndReplaceSimpleLists( Counter counter, Element parent, Collection list, String parentName, String childName) { boolean shouldExist = list != null && list.size() > 0; Element element = updateElement(counter, parent, parentName, shouldExist); if (shouldExist) { Iterator elIt = element.getChildren(childName, element.getNamespace()).iterator(); if (!elIt.hasNext()) { elIt = null; } Counter innerCount = new Counter(counter.getDepth() + 1); for (String value : list) { Element el; if (elIt != null && elIt.hasNext()) { el = elIt.next(); if (!elIt.hasNext()) { elIt = null; } } else { el = factory.element(childName, element.getNamespace()); insertAtPreferredLocation(element, el, innerCount); } el.setText(value); innerCount.increaseCount(); } if (elIt != null) { while (elIt.hasNext()) { elIt.next(); elIt.remove(); } } } return element; } /** * Method findAndReplaceXpp3DOM * * @param counter {@link Counter} * @param dom {@link Xpp3Dom} * @param name The name. * @param parent The parent. * @return {@link Element} */ protected Element findAndReplaceXpp3DOM(Counter counter, Element parent, String name, Xpp3Dom dom) { boolean shouldExist = dom != null && (dom.getChildCount() > 0 || dom.getValue() != null); Element element = updateElement(counter, parent, name, shouldExist); if (shouldExist) { replaceXpp3DOM(element, dom, new Counter(counter.getDepth() + 1)); } return element; } /** * Method insertAtPreferredLocation * * @param parent The parent. * @param counter {@link Counter} * @param child {@link Element} */ protected void insertAtPreferredLocation(Element parent, Element child, Counter counter) { int contentIndex = 0; int elementCounter = 0; Iterator it = parent.getContent().iterator(); Text lastText = null; int offset = 0; while (it.hasNext() && elementCounter <= counter.getCurrentIndex()) { Object next = it.next(); offset = offset + 1; if (next instanceof Element) { elementCounter = elementCounter + 1; contentIndex = contentIndex + offset; offset = 0; } if (next instanceof Text && it.hasNext()) { lastText = (Text) next; } } if (lastText != null && lastText.getTextTrim().length() == 0) { lastText = lastText.clone(); } else { StringBuilder starter = new StringBuilder(lineSeparator); for (int i = 0; i < counter.getDepth(); i++) { starter.append(" "); // TODO make settable? } lastText = factory.text(starter.toString()); } if (parent.getContentSize() == 0) { Text finalText = lastText.clone(); finalText.setText( finalText.getText().substring(0, finalText.getText().length() - " ".length())); parent.addContent(contentIndex, finalText); } parent.addContent(contentIndex, child); parent.addContent(contentIndex, lastText); } /** * Method iterateContributor * * @param counter {@link Counter} * @param childTag The childTag * @param parentTag The parentTag * @param list The list of elements. * @param parent The parent. */ protected void iterateContributor( Counter counter, Element parent, Collection list, String parentTag, String childTag) { boolean shouldExist = list != null && list.size() > 0; Element element = updateElement(counter, parent, parentTag, shouldExist); if (shouldExist) { Iterator elIt = element.getChildren(childTag, element.getNamespace()).iterator(); if (!elIt.hasNext()) { elIt = null; } Counter innerCount = new Counter(counter.getDepth() + 1); for (Contributor value : list) { Element el; if (elIt != null && elIt.hasNext()) { el = elIt.next(); if (!elIt.hasNext()) { elIt = null; } } else { el = factory.element(childTag, element.getNamespace()); insertAtPreferredLocation(element, el, innerCount); } updateContributor(value, childTag, innerCount, el); innerCount.increaseCount(); } if (elIt != null) { while (elIt.hasNext()) { elIt.next(); elIt.remove(); } } } } /** * Method iterateDependency * * @param counter {@link Counter} * @param childTag The childTag * @param parentTag The parentTag * @param list The list of elements. * @param parent The parent. */ protected void iterateDependency( Counter counter, Element parent, Collection list, String parentTag, String childTag) { boolean shouldExist = list != null && list.size() > 0; Element element = updateElement(counter, parent, parentTag, shouldExist); if (shouldExist) { Iterator elIt = element.getChildren(childTag, element.getNamespace()).iterator(); if (!elIt.hasNext()) { elIt = null; } Counter innerCount = new Counter(counter.getDepth() + 1); for (Dependency value : list) { Element el; if (elIt != null && elIt.hasNext()) { el = elIt.next(); if (!elIt.hasNext()) { elIt = null; } } else { el = factory.element(childTag, element.getNamespace()); insertAtPreferredLocation(element, el, innerCount); } updateDependency(value, childTag, innerCount, el); innerCount.increaseCount(); } if (elIt != null) { while (elIt.hasNext()) { elIt.next(); elIt.remove(); } } } } /** * Method iterateDeveloper * * @param counter {@link Counter} * @param childTag The childTag * @param parentTag The parentTag * @param list The list of elements. * @param parent The parent. */ protected void iterateDeveloper( Counter counter, Element parent, Collection list, String parentTag, String childTag) { boolean shouldExist = list != null && list.size() > 0; Element element = updateElement(counter, parent, parentTag, shouldExist); if (shouldExist) { Iterator elIt = element.getChildren(childTag, element.getNamespace()).iterator(); if (!elIt.hasNext()) { elIt = null; } Counter innerCount = new Counter(counter.getDepth() + 1); for (Developer value : list) { Element el; if (elIt != null && elIt.hasNext()) { el = elIt.next(); if (!elIt.hasNext()) { elIt = null; } } else { el = factory.element(childTag, element.getNamespace()); insertAtPreferredLocation(element, el, innerCount); } updateDeveloper(value, childTag, innerCount, el); innerCount.increaseCount(); } if (elIt != null) { while (elIt.hasNext()) { elIt.next(); elIt.remove(); } } } } /** * Method iterateExclusion * * @param counter {@link Counter} * @param childTag The childTag * @param parentTag The parentTag * @param list The list of elements. * @param parent The parent. */ protected void iterateExclusion( Counter counter, Element parent, Collection list, String parentTag, String childTag) { boolean shouldExist = list != null && list.size() > 0; Element element = updateElement(counter, parent, parentTag, shouldExist); if (shouldExist) { Iterator elIt = element.getChildren(childTag, element.getNamespace()).iterator(); if (!elIt.hasNext()) { elIt = null; } Counter innerCount = new Counter(counter.getDepth() + 1); for (Exclusion value : list) { Element el; if (elIt != null && elIt.hasNext()) { el = elIt.next(); if (!elIt.hasNext()) { elIt = null; } } else { el = factory.element(childTag, element.getNamespace()); insertAtPreferredLocation(element, el, innerCount); } updateExclusion(value, childTag, innerCount, el); innerCount.increaseCount(); } if (elIt != null) { while (elIt.hasNext()) { elIt.next(); elIt.remove(); } } } } /** * Method iterateExtension * * @param counter {@link Counter} * @param childTag The childTag * @param parentTag The parentTag * @param list The list of elements. * @param parent The parent. */ protected void iterateExtension( Counter counter, Element parent, Collection list, String parentTag, String childTag) { boolean shouldExist = list != null && list.size() > 0; Element element = updateElement(counter, parent, parentTag, shouldExist); if (shouldExist) { Iterator elIt = element.getChildren(childTag, element.getNamespace()).iterator(); if (!elIt.hasNext()) { elIt = null; } Counter innerCount = new Counter(counter.getDepth() + 1); for (Extension value : list) { Element el; if (elIt != null && elIt.hasNext()) { el = elIt.next(); if (!elIt.hasNext()) { elIt = null; } } else { el = factory.element(childTag, element.getNamespace()); insertAtPreferredLocation(element, el, innerCount); } updateExtension(value, childTag, innerCount, el); innerCount.increaseCount(); } if (elIt != null) { while (elIt.hasNext()) { elIt.next(); elIt.remove(); } } } } /** * Method iterateLicense * * @param counter {@link Counter} * @param childTag The childTag * @param parentTag The parentTag * @param list The list of elements. * @param parent The parent. */ protected void iterateLicense( Counter counter, Element parent, Collection list, String parentTag, String childTag) { boolean shouldExist = list != null && list.size() > 0; Element element = updateElement(counter, parent, parentTag, shouldExist); if (shouldExist) { Iterator elIt = element.getChildren(childTag, element.getNamespace()).iterator(); if (!elIt.hasNext()) { elIt = null; } Counter innerCount = new Counter(counter.getDepth() + 1); for (License value : list) { Element el; if (elIt != null && elIt.hasNext()) { el = elIt.next(); if (!elIt.hasNext()) { elIt = null; } } else { el = factory.element(childTag, element.getNamespace()); insertAtPreferredLocation(element, el, innerCount); } updateLicense(value, childTag, innerCount, el); innerCount.increaseCount(); } if (elIt != null) { while (elIt.hasNext()) { elIt.next(); elIt.remove(); } } } } /** * Method iterateMailingList * * @param counter {@link Counter} * @param childTag The childTag * @param parentTag The parentTag * @param list The list of elements. * @param parent The parent. */ protected void iterateMailingList( Counter counter, Element parent, Collection list, String parentTag, String childTag) { boolean shouldExist = list != null && list.size() > 0; Element element = updateElement(counter, parent, parentTag, shouldExist); if (shouldExist) { Iterator elIt = element.getChildren(childTag, element.getNamespace()).iterator(); if (!elIt.hasNext()) { elIt = null; } Counter innerCount = new Counter(counter.getDepth() + 1); for (MailingList value : list) { Element el; if (elIt != null && elIt.hasNext()) { el = elIt.next(); if (!elIt.hasNext()) { elIt = null; } } else { el = factory.element(childTag, element.getNamespace()); insertAtPreferredLocation(element, el, innerCount); } updateMailingList(value, childTag, innerCount, el); innerCount.increaseCount(); } if (elIt != null) { while (elIt.hasNext()) { elIt.next(); elIt.remove(); } } } } /** * Method iterateNotifier * * @param counter {@link Counter} * @param childTag The childTag * @param parentTag The parentTag * @param list The list of elements. * @param parent The parent. */ protected void iterateNotifier( Counter counter, Element parent, Collection list, String parentTag, String childTag) { boolean shouldExist = list != null && list.size() > 0; Element element = updateElement(counter, parent, parentTag, shouldExist); if (shouldExist) { Iterator elIt = element.getChildren(childTag, element.getNamespace()).iterator(); if (!elIt.hasNext()) { elIt = null; } Counter innerCount = new Counter(counter.getDepth() + 1); for (Notifier value : list) { Element el; if (elIt != null && elIt.hasNext()) { el = elIt.next(); if (!elIt.hasNext()) { elIt = null; } } else { el = factory.element(childTag, element.getNamespace()); insertAtPreferredLocation(element, el, innerCount); } updateNotifier(value, childTag, innerCount, el); innerCount.increaseCount(); } if (elIt != null) { while (elIt.hasNext()) { elIt.next(); elIt.remove(); } } } } /** * Method iteratePlugin * * @param counter {@link Counter} * @param childTag The childTag * @param parentTag The parentTag * @param list The list of elements. * @param parent The parent. */ protected void iteratePlugin( Counter counter, Element parent, Collection list, String parentTag, String childTag) { boolean shouldExist = list != null && list.size() > 0; Element element = updateElement(counter, parent, parentTag, shouldExist); if (shouldExist) { Iterator elIt = element.getChildren(childTag, element.getNamespace()).iterator(); if (!elIt.hasNext()) { elIt = null; } Counter innerCount = new Counter(counter.getDepth() + 1); for (Plugin value : list) { Element el; if (elIt != null && elIt.hasNext()) { el = elIt.next(); if (!elIt.hasNext()) { elIt = null; } } else { el = factory.element(childTag, element.getNamespace()); insertAtPreferredLocation(element, el, innerCount); } updatePlugin(value, childTag, innerCount, el); innerCount.increaseCount(); } if (elIt != null) { while (elIt.hasNext()) { elIt.next(); elIt.remove(); } } } } /** * Method iteratePluginExecution * * @param counter {@link Counter} * @param childTag The childTag * @param parentTag The parentTag * @param list The list of elements. * @param parent The parent. */ protected void iteratePluginExecution( Counter counter, Element parent, Collection list, String parentTag, String childTag) { boolean shouldExist = list != null && list.size() > 0; Element element = updateElement(counter, parent, parentTag, shouldExist); if (shouldExist) { Iterator elIt = element.getChildren(childTag, element.getNamespace()).iterator(); if (!elIt.hasNext()) { elIt = null; } Counter innerCount = new Counter(counter.getDepth() + 1); for (PluginExecution value : list) { Element el; if (elIt != null && elIt.hasNext()) { el = elIt.next(); if (!elIt.hasNext()) { elIt = null; } } else { el = factory.element(childTag, element.getNamespace()); insertAtPreferredLocation(element, el, innerCount); } updatePluginExecution(value, childTag, innerCount, el); innerCount.increaseCount(); } if (elIt != null) { while (elIt.hasNext()) { elIt.next(); elIt.remove(); } } } } /** * Method iterateProfile * * @param counter {@link Counter} * @param childTag The childTag * @param parentTag The parentTag * @param list The list of elements. * @param parent The parent. */ protected void iterateProfile( Counter counter, Element parent, Collection list, String parentTag, String childTag) { boolean shouldExist = list != null && list.size() > 0; Element element = updateElement(counter, parent, parentTag, shouldExist); if (shouldExist) { Iterator elIt = element.getChildren(childTag, element.getNamespace()).iterator(); if (!elIt.hasNext()) { elIt = null; } Counter innerCount = new Counter(counter.getDepth() + 1); for (Profile value : list) { Element el; if (elIt != null && elIt.hasNext()) { el = elIt.next(); if (!elIt.hasNext()) { elIt = null; } } else { el = factory.element(childTag, element.getNamespace()); insertAtPreferredLocation(element, el, innerCount); } updateProfile(value, childTag, innerCount, el); innerCount.increaseCount(); } if (elIt != null) { while (elIt.hasNext()) { elIt.next(); elIt.remove(); } } } } /** * Method iterateReportPlugin * * @param counter {@link Counter} * @param childTag The childTag * @param parentTag The parentTag * @param list The list of elements. * @param parent The parent. */ protected void iterateReportPlugin( Counter counter, Element parent, Collection list, String parentTag, String childTag) { boolean shouldExist = list != null && list.size() > 0; Element element = updateElement(counter, parent, parentTag, shouldExist); if (shouldExist) { Iterator elIt = element.getChildren(childTag, element.getNamespace()).iterator(); if (!elIt.hasNext()) { elIt = null; } Counter innerCount = new Counter(counter.getDepth() + 1); for (ReportPlugin value : list) { Element el; if (elIt != null && elIt.hasNext()) { el = elIt.next(); if (!elIt.hasNext()) { elIt = null; } } else { el = factory.element(childTag, element.getNamespace()); insertAtPreferredLocation(element, el, innerCount); } updateReportPlugin(value, childTag, innerCount, el); innerCount.increaseCount(); } if (elIt != null) { while (elIt.hasNext()) { elIt.next(); elIt.remove(); } } } } /** * Method iterateReportSet * * @param counter {@link Counter} * @param childTag The childTag * @param parentTag The parentTag * @param list The list of elements. * @param parent The parent. */ protected void iterateReportSet( Counter counter, Element parent, Collection list, String parentTag, String childTag) { boolean shouldExist = list != null && list.size() > 0; Element element = updateElement(counter, parent, parentTag, shouldExist); if (shouldExist) { Iterator elIt = element.getChildren(childTag, element.getNamespace()).iterator(); if (!elIt.hasNext()) { elIt = null; } Counter innerCount = new Counter(counter.getDepth() + 1); for (ReportSet value : list) { Element el; if (elIt != null && elIt.hasNext()) { el = elIt.next(); if (!elIt.hasNext()) { elIt = null; } } else { el = factory.element(childTag, element.getNamespace()); insertAtPreferredLocation(element, el, innerCount); } updateReportSet(value, childTag, innerCount, el); innerCount.increaseCount(); } if (elIt != null) { while (elIt.hasNext()) { elIt.next(); elIt.remove(); } } } } /** * Method iterateRepository * * @param counter {@link Counter} * @param childTag The childTag * @param parentTag The parentTag * @param list The list of elements. * @param parent The parent. */ protected void iterateRepository( Counter counter, Element parent, Collection list, String parentTag, String childTag) { boolean shouldExist = list != null && list.size() > 0; Element element = updateElement(counter, parent, parentTag, shouldExist); if (shouldExist) { Iterator elIt = element.getChildren(childTag, element.getNamespace()).iterator(); if (!elIt.hasNext()) { elIt = null; } Counter innerCount = new Counter(counter.getDepth() + 1); for (Repository value : list) { Element el; if (elIt != null && elIt.hasNext()) { el = elIt.next(); if (!elIt.hasNext()) { elIt = null; } } else { el = factory.element(childTag, element.getNamespace()); insertAtPreferredLocation(element, el, innerCount); } updateRepository(value, childTag, innerCount, el); innerCount.increaseCount(); } if (elIt != null) { while (elIt.hasNext()) { elIt.next(); elIt.remove(); } } } } /** * Method iterateResource * * @param counter {@link Counter} * @param childTag The childTag * @param parentTag The parentTag * @param list The list of elements. * @param parent The parent. */ protected void iterateResource( Counter counter, Element parent, Collection list, String parentTag, String childTag) { boolean shouldExist = list != null && list.size() > 0; Element element = updateElement(counter, parent, parentTag, shouldExist); if (shouldExist) { Iterator elIt = element.getChildren(childTag, element.getNamespace()).iterator(); if (!elIt.hasNext()) { elIt = null; } Counter innerCount = new Counter(counter.getDepth() + 1); for (Resource value : list) { Element el; if (elIt != null && elIt.hasNext()) { el = elIt.next(); if (!elIt.hasNext()) { elIt = null; } } else { el = factory.element(childTag, element.getNamespace()); insertAtPreferredLocation(element, el, innerCount); } updateResource(value, childTag, innerCount, el); innerCount.increaseCount(); } if (elIt != null) { while (elIt.hasNext()) { elIt.next(); elIt.remove(); } } } } /** * Method replaceXpp3DOM * * @param parent The parent. * @param counter {@link Counter} * @param parentDom {@link Element} */ protected void replaceXpp3DOM(Element parent, Xpp3Dom parentDom, Counter counter) { if (parentDom.getChildCount() > 0) { Xpp3Dom[] childs = parentDom.getChildren(); Collection domChilds = new ArrayList<>(); Collections.addAll(domChilds, childs); // int domIndex = 0; for (Element elem : parent.getChildren()) { Xpp3Dom corrDom = null; for (Xpp3Dom dm : domChilds) { if (dm.getName().equals(elem.getName())) { corrDom = dm; break; } } if (corrDom != null) { domChilds.remove(corrDom); replaceXpp3DOM(elem, corrDom, new Counter(counter.getDepth() + 1)); counter.increaseCount(); } else { parent.removeContent(elem); } } for (Xpp3Dom dm : domChilds) { Element elem = factory.element(dm.getName(), parent.getNamespace()); insertAtPreferredLocation(parent, elem, counter); counter.increaseCount(); replaceXpp3DOM(elem, dm, new Counter(counter.getDepth() + 1)); } } else if (parentDom.getValue() != null) { parent.setText(parentDom.getValue()); } } /** * Method updateActivationFile * * @param value The value. * @param element {@link Element} * @param counter {@link Counter} * @param xmlTag The XMLTag. */ protected void updateActivationFile(ActivationFile value, String xmlTag, Counter counter, Element element) { boolean shouldExist = value != null; Element root = updateElement(counter, element, xmlTag, shouldExist); if (shouldExist) { Counter innerCount = new Counter(counter.getDepth() + 1); findAndReplaceSimpleElement(innerCount, root, "missing", value.getMissing(), null); findAndReplaceSimpleElement(innerCount, root, "exists", value.getExists(), null); } } /** * Method updateActivationOS * * @param value The value. * @param element {@link Element} * @param counter {@link Counter} * @param xmlTag The XMLTag. */ protected void updateActivationOS(ActivationOS value, String xmlTag, Counter counter, Element element) { boolean shouldExist = value != null; Element root = updateElement(counter, element, xmlTag, shouldExist); if (shouldExist) { Counter innerCount = new Counter(counter.getDepth() + 1); findAndReplaceSimpleElement(innerCount, root, "name", value.getName(), null); findAndReplaceSimpleElement(innerCount, root, "family", value.getFamily(), null); findAndReplaceSimpleElement(innerCount, root, "arch", value.getArch(), null); findAndReplaceSimpleElement(innerCount, root, "version", value.getVersion(), null); } } /** * Method updateActivationProperty * * @param value The value. * @param element {@link Element} * @param counter {@link Counter} * @param xmlTag The XMLTag. */ protected void updateActivationProperty(ActivationProperty value, String xmlTag, Counter counter, Element element) { boolean shouldExist = value != null; Element root = updateElement(counter, element, xmlTag, shouldExist); if (shouldExist) { Counter innerCount = new Counter(counter.getDepth() + 1); findAndReplaceSimpleElement(innerCount, root, "name", value.getName(), null); findAndReplaceSimpleElement(innerCount, root, "value", value.getValue(), null); } } /** * Method updateBuild * * @param value The value. * @param element {@link Element} * @param counter {@link Counter} * @param xmlTag The XMLTag. */ // CHECKSTYLE_OFF: LineLength protected void updateBuild(Build value, String xmlTag, Counter counter, Element element) { boolean shouldExist = value != null; Element root = updateElement(counter, element, xmlTag, shouldExist); if (shouldExist) { Counter innerCount = new Counter(counter.getDepth() + 1); findAndReplaceSimpleElement(innerCount, root, "sourceDirectory", value.getSourceDirectory(), null); findAndReplaceSimpleElement( innerCount, root, "scriptSourceDirectory", value.getScriptSourceDirectory(), null); findAndReplaceSimpleElement(innerCount, root, "testSourceDirectory", value.getTestSourceDirectory(), null); findAndReplaceSimpleElement(innerCount, root, "outputDirectory", value.getOutputDirectory(), null); findAndReplaceSimpleElement(innerCount, root, "testOutputDirectory", value.getTestOutputDirectory(), null); iterateExtension(innerCount, root, value.getExtensions(), "extensions", "extension"); findAndReplaceSimpleElement(innerCount, root, "defaultGoal", value.getDefaultGoal(), null); iterateResource(innerCount, root, value.getResources(), "resources", "resource"); iterateResource(innerCount, root, value.getTestResources(), "testResources", "testResource"); findAndReplaceSimpleElement(innerCount, root, "directory", value.getDirectory(), null); findAndReplaceSimpleElement(innerCount, root, "finalName", value.getFinalName(), null); findAndReplaceSimpleLists(innerCount, root, value.getFilters(), "filters", "filter"); updatePluginManagement(value.getPluginManagement(), "pluginManagement", innerCount, root); iteratePlugin(innerCount, root, value.getPlugins(), "plugins", "plugin"); } } // CHECKSTYLE_ON: LineLength /** * Method updateBuildBase * * @param value The value. * @param element {@link Element} * @param counter {@link Counter} * @param xmlTag The XMLTag. */ protected void updateBuildBase(BuildBase value, String xmlTag, Counter counter, Element element) { boolean shouldExist = value != null; Element root = updateElement(counter, element, xmlTag, shouldExist); if (shouldExist) { Counter innerCount = new Counter(counter.getDepth() + 1); findAndReplaceSimpleElement(innerCount, root, "defaultGoal", value.getDefaultGoal(), null); iterateResource(innerCount, root, value.getResources(), "resources", "resource"); iterateResource(innerCount, root, value.getTestResources(), "testResources", "testResource"); findAndReplaceSimpleElement(innerCount, root, "directory", value.getDirectory(), null); findAndReplaceSimpleElement(innerCount, root, "finalName", value.getFinalName(), null); findAndReplaceSimpleLists(innerCount, root, value.getFilters(), "filters", "filter"); updatePluginManagement(value.getPluginManagement(), "pluginManagement", innerCount, root); iteratePlugin(innerCount, root, value.getPlugins(), "plugins", "plugin"); } } /** * Method updateCiManagement * * @param value The value. * @param element {@link Element} * @param counter {@link Counter} * @param xmlTag The XMLTag. */ protected void updateCiManagement(CiManagement value, String xmlTag, Counter counter, Element element) { boolean shouldExist = value != null; Element root = updateElement(counter, element, xmlTag, shouldExist); if (shouldExist) { Counter innerCount = new Counter(counter.getDepth() + 1); findAndReplaceSimpleElement(innerCount, root, "system", value.getSystem(), null); findAndReplaceSimpleElement(innerCount, root, "url", value.getUrl(), null); iterateNotifier(innerCount, root, value.getNotifiers(), "notifiers", "notifier"); } } /** * Method updateConfigurationContainer * * @param value The value. * @param element {@link Element} * @param counter {@link Counter} * @param xmlTag The XMLTag. */ protected void updateConfigurationContainer( ConfigurationContainer value, String xmlTag, Counter counter, Element element) { boolean shouldExist = value != null; Element root = updateElement(counter, element, xmlTag, shouldExist); if (shouldExist) { Counter innerCount = new Counter(counter.getDepth() + 1); findAndReplaceSimpleElement(innerCount, root, "inherited", value.getInherited(), null); findAndReplaceXpp3DOM(innerCount, root, "configuration", (Xpp3Dom) value.getConfiguration()); } } /** * Method updateContributor * * @param value The value. * @param element {@link Element} * @param counter {@link Counter} * @param xmlTag The XMLTag. */ protected void updateContributor(Contributor value, String xmlTag, Counter counter, Element element) { Element root = element; Counter innerCount = new Counter(counter.getDepth() + 1); findAndReplaceSimpleElement(innerCount, root, "name", value.getName(), null); findAndReplaceSimpleElement(innerCount, root, "email", value.getEmail(), null); findAndReplaceSimpleElement(innerCount, root, "url", value.getUrl(), null); findAndReplaceSimpleElement(innerCount, root, "organization", value.getOrganization(), null); findAndReplaceSimpleElement(innerCount, root, "organizationUrl", value.getOrganizationUrl(), null); findAndReplaceSimpleLists(innerCount, root, value.getRoles(), "roles", "role"); findAndReplaceSimpleElement(innerCount, root, "timezone", value.getTimezone(), null); findAndReplaceProperties(innerCount, root, "properties", value.getProperties()); } /** * Method updateDependency * * @param value The value. * @param element {@link Element} * @param counter {@link Counter} * @param xmlTag The XMLTag. */ protected void updateDependency(Dependency value, String xmlTag, Counter counter, Element element) { Element root = element; Counter innerCount = new Counter(counter.getDepth() + 1); findAndReplaceSimpleElement(innerCount, root, "groupId", value.getGroupId(), null); findAndReplaceSimpleElement(innerCount, root, "artifactId", value.getArtifactId(), null); findAndReplaceSimpleElement(innerCount, root, "version", value.getVersion(), null); findAndReplaceSimpleElement(innerCount, root, "type", value.getType(), "jar"); findAndReplaceSimpleElement(innerCount, root, "classifier", value.getClassifier(), null); findAndReplaceSimpleElement(innerCount, root, "scope", value.getScope(), null); findAndReplaceSimpleElement(innerCount, root, "systemPath", value.getSystemPath(), null); iterateExclusion(innerCount, root, value.getExclusions(), "exclusions", "exclusion"); findAndReplaceSimpleElement( innerCount, root, "optional", !value.isOptional() ? null : String.valueOf(value.isOptional()), "false"); } /** * Method updateDependencyManagement * * @param value The value. * @param element {@link Element} * @param counter {@link Counter} * @param xmlTag The XMLTag. */ protected void updateDependencyManagement( DependencyManagement value, String xmlTag, Counter counter, Element element) { boolean shouldExist = value != null; Element root = updateElement(counter, element, xmlTag, shouldExist); if (shouldExist) { Counter innerCount = new Counter(counter.getDepth() + 1); iterateDependency(innerCount, root, value.getDependencies(), "dependencies", "dependency"); } } /** * Method updateDeploymentRepository * * @param value The value. * @param element {@link Element} * @param counter {@link Counter} * @param xmlTag The XMLTag. */ protected void updateDeploymentRepository( DeploymentRepository value, String xmlTag, Counter counter, Element element) { boolean shouldExist = value != null; Element root = updateElement(counter, element, xmlTag, shouldExist); if (shouldExist) { Counter innerCount = new Counter(counter.getDepth() + 1); findAndReplaceSimpleElement( innerCount, root, "uniqueVersion", value.isUniqueVersion() ? null : String.valueOf(value.isUniqueVersion()), "true"); findAndReplaceSimpleElement(innerCount, root, "id", value.getId(), null); findAndReplaceSimpleElement(innerCount, root, "name", value.getName(), null); findAndReplaceSimpleElement(innerCount, root, "url", value.getUrl(), null); findAndReplaceSimpleElement(innerCount, root, "layout", value.getLayout(), "default"); } } /** * Method updateDeveloper * * @param value The value. * @param element {@link Element} * @param counter {@link Counter} * @param xmlTag The XMLTag. */ protected void updateDeveloper(Developer value, String xmlTag, Counter counter, Element element) { Element root = element; Counter innerCount = new Counter(counter.getDepth() + 1); findAndReplaceSimpleElement(innerCount, root, "id", value.getId(), null); findAndReplaceSimpleElement(innerCount, root, "name", value.getName(), null); findAndReplaceSimpleElement(innerCount, root, "email", value.getEmail(), null); findAndReplaceSimpleElement(innerCount, root, "url", value.getUrl(), null); findAndReplaceSimpleElement(innerCount, root, "organization", value.getOrganization(), null); findAndReplaceSimpleElement(innerCount, root, "organizationUrl", value.getOrganizationUrl(), null); findAndReplaceSimpleLists(innerCount, root, value.getRoles(), "roles", "role"); findAndReplaceSimpleElement(innerCount, root, "timezone", value.getTimezone(), null); findAndReplaceProperties(innerCount, root, "properties", value.getProperties()); } /** * Method updateDistributionManagement * * @param value The value. * @param element {@link Element} * @param counter {@link Counter} * @param xmlTag The XMLTag. */ protected void updateDistributionManagement( DistributionManagement value, String xmlTag, Counter counter, Element element) { boolean shouldExist = value != null; Element root = updateElement(counter, element, xmlTag, shouldExist); if (shouldExist) { Counter innerCount = new Counter(counter.getDepth() + 1); updateDeploymentRepository(value.getRepository(), "repository", innerCount, root); updateDeploymentRepository(value.getSnapshotRepository(), "snapshotRepository", innerCount, root); updateSite(value.getSite(), "site", innerCount, root); findAndReplaceSimpleElement(innerCount, root, "downloadUrl", value.getDownloadUrl(), null); updateRelocation(value.getRelocation(), "relocation", innerCount, root); findAndReplaceSimpleElement(innerCount, root, "status", value.getStatus(), null); } } /** * Method updateElement * * @param counter {@link Counter} * @param shouldExist should exist. * @param name The name. * @param parent The parent. * @return {@link Element} */ protected Element updateElement(Counter counter, Element parent, String name, boolean shouldExist) { Element element = parent.getChild(name, parent.getNamespace()); if (element != null && shouldExist) { counter.increaseCount(); } if (element == null && shouldExist) { element = factory.element(name, parent.getNamespace()); insertAtPreferredLocation(parent, element, counter); counter.increaseCount(); } if (!shouldExist && element != null) { int index = parent.indexOf(element); if (index > 0) { Content previous = parent.getContent(index - 1); if (previous instanceof Text) { Text txt = (Text) previous; if (txt.getTextTrim().length() == 0) { parent.removeContent(txt); } } } parent.removeContent(element); } return element; } /** * Method updateExclusion * * @param value The value. * @param element {@link Element} * @param counter {@link Counter} * @param xmlTag The XMLTag. */ protected void updateExclusion(Exclusion value, String xmlTag, Counter counter, Element element) { Element root = element; Counter innerCount = new Counter(counter.getDepth() + 1); findAndReplaceSimpleElement(innerCount, root, "artifactId", value.getArtifactId(), null); findAndReplaceSimpleElement(innerCount, root, "groupId", value.getGroupId(), null); } /** * Method updateExtension * * @param value The value. * @param element {@link Element} * @param counter {@link Counter} * @param xmlTag The XMLTag. */ protected void updateExtension(Extension value, String xmlTag, Counter counter, Element element) { Element root = element; Counter innerCount = new Counter(counter.getDepth() + 1); findAndReplaceSimpleElement(innerCount, root, "groupId", value.getGroupId(), null); findAndReplaceSimpleElement(innerCount, root, "artifactId", value.getArtifactId(), null); findAndReplaceSimpleElement(innerCount, root, "version", value.getVersion(), null); } /** * Method updateFileSet * * @param value The value. * @param element {@link Element} * @param counter {@link Counter} * @param xmlTag The XMLTag. */ protected void updateFileSet(FileSet value, String xmlTag, Counter counter, Element element) { boolean shouldExist = value != null; Element root = updateElement(counter, element, xmlTag, shouldExist); if (shouldExist) { Counter innerCount = new Counter(counter.getDepth() + 1); findAndReplaceSimpleElement(innerCount, root, "directory", value.getDirectory(), null); findAndReplaceSimpleLists(innerCount, root, value.getIncludes(), "includes", "include"); findAndReplaceSimpleLists(innerCount, root, value.getExcludes(), "excludes", "exclude"); } } /** * Method updateIssueManagement * * @param value The value. * @param element {@link Element} * @param counter {@link Counter} * @param xmlTag The XMLTag. */ protected void updateIssueManagement(IssueManagement value, String xmlTag, Counter counter, Element element) { boolean shouldExist = value != null; Element root = updateElement(counter, element, xmlTag, shouldExist); if (shouldExist) { Counter innerCount = new Counter(counter.getDepth() + 1); findAndReplaceSimpleElement(innerCount, root, "system", value.getSystem(), null); findAndReplaceSimpleElement(innerCount, root, "url", value.getUrl(), null); } } /** * Method updateLicense * * @param value The value. * @param element {@link Element} * @param counter {@link Counter} * @param xmlTag The XMLTag. */ protected void updateLicense(License value, String xmlTag, Counter counter, Element element) { Element root = element; Counter innerCount = new Counter(counter.getDepth() + 1); findAndReplaceSimpleElement(innerCount, root, "name", value.getName(), null); findAndReplaceSimpleElement(innerCount, root, "url", value.getUrl(), null); findAndReplaceSimpleElement(innerCount, root, "distribution", value.getDistribution(), null); findAndReplaceSimpleElement(innerCount, root, "comments", value.getComments(), null); } /** * Method updateMailingList * * @param value The value. * @param element {@link Element} * @param counter {@link Counter} * @param xmlTag The XMLTag. */ protected void updateMailingList(MailingList value, String xmlTag, Counter counter, Element element) { Element root = element; Counter innerCount = new Counter(counter.getDepth() + 1); findAndReplaceSimpleElement(innerCount, root, "name", value.getName(), null); findAndReplaceSimpleElement(innerCount, root, "subscribe", value.getSubscribe(), null); findAndReplaceSimpleElement(innerCount, root, "unsubscribe", value.getUnsubscribe(), null); findAndReplaceSimpleElement(innerCount, root, "post", value.getPost(), null); findAndReplaceSimpleElement(innerCount, root, "archive", value.getArchive(), null); findAndReplaceSimpleLists(innerCount, root, value.getOtherArchives(), "otherArchives", "otherArchive"); } /** * Method updateModel * * @param value The value. * @param element {@link Element} * @param counter {@link Counter} * @param xmlTag The XMLTag. */ protected void updateModel(Model value, String xmlTag, Counter counter, Element element) { Element root = element; Counter innerCount = new Counter(counter.getDepth() + 1); updateParent(value.getParent(), "parent", innerCount, root); findAndReplaceSimpleElement(innerCount, root, "modelVersion", value.getModelVersion(), null); findAndReplaceSimpleElement(innerCount, root, "groupId", value.getGroupId(), null); findAndReplaceSimpleElement(innerCount, root, "artifactId", value.getArtifactId(), null); findAndReplaceSimpleElement(innerCount, root, "packaging", value.getPackaging(), "jar"); findAndReplaceSimpleElement(innerCount, root, "name", value.getName(), null); findAndReplaceSimpleElement(innerCount, root, "version", value.getVersion(), null); findAndReplaceSimpleElement(innerCount, root, "description", value.getDescription(), null); findAndReplaceSimpleElement(innerCount, root, "url", value.getUrl(), null); updatePrerequisites(value.getPrerequisites(), "prerequisites", innerCount, root); updateIssueManagement(value.getIssueManagement(), "issueManagement", innerCount, root); updateCiManagement(value.getCiManagement(), "ciManagement", innerCount, root); findAndReplaceSimpleElement(innerCount, root, "inceptionYear", value.getInceptionYear(), null); iterateMailingList(innerCount, root, value.getMailingLists(), "mailingLists", "mailingList"); iterateDeveloper(innerCount, root, value.getDevelopers(), "developers", "developer"); iterateContributor(innerCount, root, value.getContributors(), "contributors", "contributor"); iterateLicense(innerCount, root, value.getLicenses(), "licenses", "license"); updateScm(value.getScm(), "scm", innerCount, root); updateOrganization(value.getOrganization(), "organization", innerCount, root); updateBuild(value.getBuild(), "build", innerCount, root); iterateProfile(innerCount, root, value.getProfiles(), "profiles", "profile"); findAndReplaceSimpleLists(innerCount, root, value.getModules(), "modules", "module"); iterateRepository(innerCount, root, value.getRepositories(), "repositories", "repository"); iterateRepository(innerCount, root, value.getPluginRepositories(), "pluginRepositories", "pluginRepository"); iterateDependency(innerCount, root, value.getDependencies(), "dependencies", "dependency"); updateReporting(value.getReporting(), "reporting", innerCount, root); updateDependencyManagement(value.getDependencyManagement(), "dependencyManagement", innerCount, root); updateDistributionManagement(value.getDistributionManagement(), "distributionManagement", innerCount, root); findAndReplaceProperties(innerCount, root, "properties", value.getProperties()); } /** * Method updateModelBase * * @param value The value. * @param element {@link Element} * @param counter {@link Counter} * @param xmlTag The XMLTag. */ // CHECKSTYLE_OFF: LineLength protected void updateModelBase(ModelBase value, String xmlTag, Counter counter, Element element) { boolean shouldExist = value != null; Element root = updateElement(counter, element, xmlTag, shouldExist); if (shouldExist) { Counter innerCount = new Counter(counter.getDepth() + 1); findAndReplaceSimpleLists(innerCount, root, value.getModules(), "modules", "module"); iterateRepository(innerCount, root, value.getRepositories(), "repositories", "repository"); iterateRepository( innerCount, root, value.getPluginRepositories(), "pluginRepositories", "pluginRepository"); iterateDependency(innerCount, root, value.getDependencies(), "dependencies", "dependency"); updateReporting(value.getReporting(), "reporting", innerCount, root); updateDependencyManagement(value.getDependencyManagement(), "dependencyManagement", innerCount, root); updateDistributionManagement(value.getDistributionManagement(), "distributionManagement", innerCount, root); findAndReplaceProperties(innerCount, root, "properties", value.getProperties()); } } // CHECKSTYLE_ON: LineLength /** * Method updateNotifier * * @param value The value. * @param element {@link Element} * @param counter {@link Counter} * @param xmlTag The XMLTag. */ // CHECKSTYLE_OFF: LineLength protected void updateNotifier(Notifier value, String xmlTag, Counter counter, Element element) { Element root = element; Counter innerCount = new Counter(counter.getDepth() + 1); findAndReplaceSimpleElement(innerCount, root, "type", value.getType(), "mail"); findAndReplaceSimpleElement( innerCount, root, "sendOnError", value.isSendOnError() ? null : String.valueOf(value.isSendOnError()), "true"); findAndReplaceSimpleElement( innerCount, root, "sendOnFailure", value.isSendOnFailure() ? null : String.valueOf(value.isSendOnFailure()), "true"); findAndReplaceSimpleElement( innerCount, root, "sendOnSuccess", value.isSendOnSuccess() ? null : String.valueOf(value.isSendOnSuccess()), "true"); findAndReplaceSimpleElement( innerCount, root, "sendOnWarning", value.isSendOnWarning() ? null : String.valueOf(value.isSendOnWarning()), "true"); findAndReplaceSimpleElement(innerCount, root, "address", value.getAddress(), null); findAndReplaceProperties(innerCount, root, "configuration", value.getConfiguration()); } // CHECKSTYLE_ON: LineLength /** * Method updateOrganization * * @param value The value. * @param element {@link Element} * @param counter {@link Counter} * @param xmlTag The XMLTag. */ protected void updateOrganization(Organization value, String xmlTag, Counter counter, Element element) { boolean shouldExist = value != null; Element root = updateElement(counter, element, xmlTag, shouldExist); if (shouldExist) { Counter innerCount = new Counter(counter.getDepth() + 1); findAndReplaceSimpleElement(innerCount, root, "name", value.getName(), null); findAndReplaceSimpleElement(innerCount, root, "url", value.getUrl(), null); } } /** * Method updateParent * * @param value The value. * @param element {@link Element} * @param counter {@link Counter} * @param xmlTag The XMLTag. */ protected void updateParent(Parent value, String xmlTag, Counter counter, Element element) { boolean shouldExist = value != null; Element root = updateElement(counter, element, xmlTag, shouldExist); if (shouldExist) { Counter innerCount = new Counter(counter.getDepth() + 1); findAndReplaceSimpleElement(innerCount, root, "artifactId", value.getArtifactId(), null); findAndReplaceSimpleElement(innerCount, root, "groupId", value.getGroupId(), null); findAndReplaceSimpleElement(innerCount, root, "version", value.getVersion(), null); findAndReplaceSimpleElement(innerCount, root, "relativePath", value.getRelativePath(), "../pom.xml"); } } /** * Method updatePatternSet * * @param value The value. * @param element {@link Element} * @param counter {@link Counter} * @param xmlTag The XMLTag. */ protected void updatePatternSet(PatternSet value, String xmlTag, Counter counter, Element element) { boolean shouldExist = value != null; Element root = updateElement(counter, element, xmlTag, shouldExist); if (shouldExist) { Counter innerCount = new Counter(counter.getDepth() + 1); findAndReplaceSimpleLists(innerCount, root, value.getIncludes(), "includes", "include"); findAndReplaceSimpleLists(innerCount, root, value.getExcludes(), "excludes", "exclude"); } } /** * Method updatePlugin * * @param value The value. * @param element {@link Element} * @param counter {@link Counter} * @param xmlTag The XMLTag. */ protected void updatePlugin(Plugin value, String xmlTag, Counter counter, Element element) { Element root = element; Counter innerCount = new Counter(counter.getDepth() + 1); findAndReplaceSimpleElement(innerCount, root, "groupId", value.getGroupId(), "org.apache.maven.plugins"); findAndReplaceSimpleElement(innerCount, root, "artifactId", value.getArtifactId(), null); findAndReplaceSimpleElement(innerCount, root, "version", value.getVersion(), null); findAndReplaceSimpleElement( innerCount, root, "extensions", !value.isExtensions() ? null : String.valueOf(value.isExtensions()), "false"); iteratePluginExecution(innerCount, root, value.getExecutions(), "executions", "execution"); iterateDependency(innerCount, root, value.getDependencies(), "dependencies", "dependency"); findAndReplaceSimpleElement(innerCount, root, "inherited", value.getInherited(), null); findAndReplaceXpp3DOM(innerCount, root, "configuration", (Xpp3Dom) value.getConfiguration()); } /** * Method updatePluginConfiguration * * @param value The value. * @param element {@link Element} * @param counter {@link Counter} * @param xmlTag The XMLTag. */ // CHECKSTYLE_OFF: LineLength protected void updatePluginConfiguration( PluginConfiguration value, String xmlTag, Counter counter, Element element) { boolean shouldExist = value != null; Element root = updateElement(counter, element, xmlTag, shouldExist); if (shouldExist) { Counter innerCount = new Counter(counter.getDepth() + 1); updatePluginManagement(value.getPluginManagement(), "pluginManagement", innerCount, root); iteratePlugin(innerCount, root, value.getPlugins(), "plugins", "plugin"); } } // CHECKSTYLE_ON: LineLength /** * Method updatePluginContainer * * @param value The value. * @param element {@link Element} * @param counter {@link Counter} * @param xmlTag The XMLTag. */ protected void updatePluginContainer(PluginContainer value, String xmlTag, Counter counter, Element element) { boolean shouldExist = value != null; Element root = updateElement(counter, element, xmlTag, shouldExist); if (shouldExist) { Counter innerCount = new Counter(counter.getDepth() + 1); iteratePlugin(innerCount, root, value.getPlugins(), "plugins", "plugin"); } } /** * Method updatePluginExecution * * @param value The value. * @param element {@link Element} * @param counter {@link Counter} * @param xmlTag The XMLTag. */ protected void updatePluginExecution(PluginExecution value, String xmlTag, Counter counter, Element element) { Element root = element; Counter innerCount = new Counter(counter.getDepth() + 1); findAndReplaceSimpleElement(innerCount, root, "id", value.getId(), "default"); findAndReplaceSimpleElement(innerCount, root, "phase", value.getPhase(), null); findAndReplaceSimpleLists(innerCount, root, value.getGoals(), "goals", "goal"); findAndReplaceSimpleElement(innerCount, root, "inherited", value.getInherited(), null); findAndReplaceXpp3DOM(innerCount, root, "configuration", (Xpp3Dom) value.getConfiguration()); } /** * Method updatePluginManagement * * @param value The value. * @param element {@link Element} * @param counter {@link Counter} * @param xmlTag The XMLTag. */ protected void updatePluginManagement(PluginManagement value, String xmlTag, Counter counter, Element element) { boolean shouldExist = value != null; Element root = updateElement(counter, element, xmlTag, shouldExist); if (shouldExist) { Counter innerCount = new Counter(counter.getDepth() + 1); iteratePlugin(innerCount, root, value.getPlugins(), "plugins", "plugin"); } } /** * Method updatePrerequisites * * @param value The value. * @param element {@link Element} * @param counter {@link Counter} * @param xmlTag The XMLTag. */ protected void updatePrerequisites(Prerequisites value, String xmlTag, Counter counter, Element element) { boolean shouldExist = value != null; Element root = updateElement(counter, element, xmlTag, shouldExist); if (shouldExist) { Counter innerCount = new Counter(counter.getDepth() + 1); findAndReplaceSimpleElement(innerCount, root, "maven", value.getMaven(), "2.0"); } } /** * Method updateProfile * * @param value The value. * @param element {@link Element} * @param counter {@link Counter} * @param xmlTag The XMLTag. */ protected void updateProfile(Profile value, String xmlTag, Counter counter, Element element) { Element root = element; Counter innerCount = new Counter(counter.getDepth() + 1); findAndReplaceSimpleElement(innerCount, root, "id", value.getId(), "default"); // updateActivation( value.getActivation(), "activation", innerCount, root); updateBuildBase(value.getBuild(), "build", innerCount, root); findAndReplaceSimpleLists(innerCount, root, value.getModules(), "modules", "module"); iterateRepository(innerCount, root, value.getRepositories(), "repositories", "repository"); iterateRepository(innerCount, root, value.getPluginRepositories(), "pluginRepositories", "pluginRepository"); iterateDependency(innerCount, root, value.getDependencies(), "dependencies", "dependency"); updateReporting(value.getReporting(), "reporting", innerCount, root); updateDependencyManagement(value.getDependencyManagement(), "dependencyManagement", innerCount, root); updateDistributionManagement(value.getDistributionManagement(), "distributionManagement", innerCount, root); findAndReplaceProperties(innerCount, root, "properties", value.getProperties()); } /** * Method updateRelocation * * @param value The value. * @param element {@link Element} * @param counter {@link Counter} * @param xmlTag The XMLTag. */ protected void updateRelocation(Relocation value, String xmlTag, Counter counter, Element element) { boolean shouldExist = value != null; Element root = updateElement(counter, element, xmlTag, shouldExist); if (shouldExist) { Counter innerCount = new Counter(counter.getDepth() + 1); findAndReplaceSimpleElement(innerCount, root, "groupId", value.getGroupId(), null); findAndReplaceSimpleElement(innerCount, root, "artifactId", value.getArtifactId(), null); findAndReplaceSimpleElement(innerCount, root, "version", value.getVersion(), null); findAndReplaceSimpleElement(innerCount, root, "message", value.getMessage(), null); } } /** * Method updateReportPlugin * * @param value The value. * @param element {@link Element} * @param counter {@link Counter} * @param xmlTag The XMLTag. */ protected void updateReportPlugin(ReportPlugin value, String xmlTag, Counter counter, Element element) { Element root = element; Counter innerCount = new Counter(counter.getDepth() + 1); findAndReplaceSimpleElement(innerCount, root, "groupId", value.getGroupId(), "org.apache.maven.plugins"); findAndReplaceSimpleElement(innerCount, root, "artifactId", value.getArtifactId(), null); findAndReplaceSimpleElement(innerCount, root, "version", value.getVersion(), null); findAndReplaceSimpleElement(innerCount, root, "inherited", value.getInherited(), null); findAndReplaceXpp3DOM(innerCount, root, "configuration", (Xpp3Dom) value.getConfiguration()); iterateReportSet(innerCount, root, value.getReportSets(), "reportSets", "reportSet"); } /** * Method updateReportSet * * @param value The value. * @param element {@link Element} * @param counter {@link Counter} * @param xmlTag The XMLTag. */ protected void updateReportSet(ReportSet value, String xmlTag, Counter counter, Element element) { Element root = element; Counter innerCount = new Counter(counter.getDepth() + 1); findAndReplaceSimpleElement(innerCount, root, "id", value.getId(), "default"); findAndReplaceXpp3DOM(innerCount, root, "configuration", (Xpp3Dom) value.getConfiguration()); findAndReplaceSimpleElement(innerCount, root, "inherited", value.getInherited(), null); findAndReplaceSimpleLists(innerCount, root, value.getReports(), "reports", "report"); } /** * Method updateReporting * * @param value The value. * @param element {@link Element} * @param counter {@link Counter} * @param xmlTag The XMLTag. */ protected void updateReporting(Reporting value, String xmlTag, Counter counter, Element element) { boolean shouldExist = value != null; Element root = updateElement(counter, element, xmlTag, shouldExist); if (shouldExist) { Counter innerCount = new Counter(counter.getDepth() + 1); findAndReplaceSimpleElement( innerCount, root, "excludeDefaults", !value.isExcludeDefaults() ? null : String.valueOf(value.isExcludeDefaults()), "false"); findAndReplaceSimpleElement(innerCount, root, "outputDirectory", value.getOutputDirectory(), null); iterateReportPlugin(innerCount, root, value.getPlugins(), "plugins", "plugin"); } } /** * Method updateRepository * * @param value The value. * @param element {@link Element} * @param counter {@link Counter} * @param xmlTag The XMLTag. */ protected void updateRepository(Repository value, String xmlTag, Counter counter, Element element) { Element root = element; Counter innerCount = new Counter(counter.getDepth() + 1); updateRepositoryPolicy(value.getReleases(), "releases", innerCount, root); updateRepositoryPolicy(value.getSnapshots(), "snapshots", innerCount, root); findAndReplaceSimpleElement(innerCount, root, "id", value.getId(), null); findAndReplaceSimpleElement(innerCount, root, "name", value.getName(), null); findAndReplaceSimpleElement(innerCount, root, "url", value.getUrl(), null); findAndReplaceSimpleElement(innerCount, root, "layout", value.getLayout(), "default"); } /** * Method updateRepositoryBase * * @param value The value. * @param element {@link Element} * @param counter {@link Counter} * @param xmlTag The XMLTag. */ protected void updateRepositoryBase(RepositoryBase value, String xmlTag, Counter counter, Element element) { boolean shouldExist = value != null; Element root = updateElement(counter, element, xmlTag, shouldExist); if (shouldExist) { Counter innerCount = new Counter(counter.getDepth() + 1); findAndReplaceSimpleElement(innerCount, root, "id", value.getId(), null); findAndReplaceSimpleElement(innerCount, root, "name", value.getName(), null); findAndReplaceSimpleElement(innerCount, root, "url", value.getUrl(), null); findAndReplaceSimpleElement(innerCount, root, "layout", value.getLayout(), "default"); } } /** * Method updateRepositoryPolicy * * @param value The value. * @param element {@link Element} * @param counter {@link Counter} * @param xmlTag The XMLTag. */ protected void updateRepositoryPolicy(RepositoryPolicy value, String xmlTag, Counter counter, Element element) { boolean shouldExist = value != null; Element root = updateElement(counter, element, xmlTag, shouldExist); if (shouldExist) { Counter innerCount = new Counter(counter.getDepth() + 1); findAndReplaceSimpleElement( innerCount, root, "enabled", value.isEnabled() ? null : String.valueOf(value.isEnabled()), "true"); findAndReplaceSimpleElement(innerCount, root, "updatePolicy", value.getUpdatePolicy(), null); findAndReplaceSimpleElement(innerCount, root, "checksumPolicy", value.getChecksumPolicy(), null); } } /** * Method updateResource * * @param value The value. * @param element {@link Element} * @param counter {@link Counter} * @param xmlTag The XMLTag. */ protected void updateResource(Resource value, String xmlTag, Counter counter, Element element) { Element root = element; Counter innerCount = new Counter(counter.getDepth() + 1); findAndReplaceSimpleElement(innerCount, root, "targetPath", value.getTargetPath(), null); findAndReplaceSimpleElement( innerCount, root, "filtering", !value.isFiltering() ? null : String.valueOf(value.isFiltering()), "false"); findAndReplaceSimpleElement(innerCount, root, "directory", value.getDirectory(), null); findAndReplaceSimpleLists(innerCount, root, value.getIncludes(), "includes", "include"); findAndReplaceSimpleLists(innerCount, root, value.getExcludes(), "excludes", "exclude"); } /** * Method updateScm * * @param value The value. * @param element {@link Element} * @param counter {@link Counter} * @param xmlTag The XMLTag. */ protected void updateScm(Scm value, String xmlTag, Counter counter, Element element) { boolean shouldExist = value != null; Element root = updateElement(counter, element, xmlTag, shouldExist); if (shouldExist) { // CHECKSTYLE_OFF: LineLength Counter innerCount = new Counter(counter.getDepth() + 1); findAndReplaceSimpleElement(innerCount, root, "connection", value.getConnection(), null); findAndReplaceSimpleElement(innerCount, root, "developerConnection", value.getDeveloperConnection(), null); findAndReplaceSimpleElement(innerCount, root, "tag", value.getTag(), "HEAD"); findAndReplaceSimpleElement(innerCount, root, "url", value.getUrl(), null); // CHECKSTYLE_ON: LineLength } } /** * Method updateSite * * @param value The value. * @param element {@link Element} * @param counter {@link Counter} * @param xmlTag The XMLTag. */ protected void updateSite(Site value, String xmlTag, Counter counter, Element element) { boolean shouldExist = value != null; Element root = updateElement(counter, element, xmlTag, shouldExist); if (shouldExist) { Counter innerCount = new Counter(counter.getDepth() + 1); findAndReplaceSimpleElement(innerCount, root, "id", value.getId(), null); findAndReplaceSimpleElement(innerCount, root, "name", value.getName(), null); findAndReplaceSimpleElement(innerCount, root, "url", value.getUrl(), null); } } /** * Method write * * @param project {@link Model} * @param stream {@link OutputStream} * @param document {@link Document} * @deprecated * @throws IOException in case of an error. */ public void write(Model project, Document document, OutputStream stream) throws IOException { updateModel(project, "project", new Counter(0), document.getRootElement()); XMLOutputter outputter = new XMLOutputter(); Format format = Format.getPrettyFormat(); format.setIndent(" ").setLineSeparator(lineSeparator); outputter.setFormat(format); outputter.output(document, stream); } /** * Method write * * @param project {@link Model} * @param writer {@link OutputStreamWriter} * @param document {@link Document} * @throws IOException in case of an error. */ public void write(Model project, Document document, OutputStreamWriter writer) throws IOException { Format format = Format.getRawFormat(); format.setEncoding(writer.getEncoding()).setLineSeparator(lineSeparator); write(project, document, writer, format); } /** * Method write * * @param project {@link Model} * @param jdomFormat {@link Format} * @param writer {@link Writer} * @param document {@link Document} * @throws IOException in case of an error. */ public void write(Model project, Document document, Writer writer, Format jdomFormat) throws IOException { updateModel(project, "project", new Counter(0), document.getRootElement()); XMLOutputter outputter = new XMLOutputter(); outputter.setFormat(jdomFormat); outputter.output(document, writer); } } ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/pom/PomWriter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.pom; import java.io.IOException; import java.io.Writer; import org.apache.maven.model.Model; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.Namespace; import org.jdom2.output.Format; /** * @author Jason van Zyl */ public class PomWriter { public static void write(Writer w, Model newModel) throws IOException { write(w, newModel, false); } public static void write(Writer w, Model newModel, boolean namespaceDeclaration) throws IOException { Element root = new Element("project"); if (namespaceDeclaration) { String modelVersion = newModel.getModelVersion(); Namespace pomNamespace = Namespace.getNamespace("", "http://maven.apache.org/POM/" + modelVersion); root.setNamespace(pomNamespace); Namespace xsiNamespace = Namespace.getNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance"); root.addNamespaceDeclaration(xsiNamespace); if (root.getAttribute("schemaLocation", xsiNamespace) == null) { root.setAttribute( "schemaLocation", "http://maven.apache.org/POM/" + modelVersion + " http://maven.apache.org/maven-v" + modelVersion.replace('.', '_') + ".xsd", xsiNamespace); } } Document doc = new Document(root); MavenJDOMWriter writer = new MavenJDOMWriter(); String encoding = newModel.getModelEncoding() != null ? newModel.getModelEncoding() : "UTF-8"; Format format = Format.getPrettyFormat().setEncoding(encoding); writer.write(newModel, doc, w, format); } } ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/relocation/Relocator.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.relocation; /** @author Jason van Zyl */ public interface Relocator { String ROLE = Relocator.class.getName(); boolean canRelocatePath(String clazz); String relocatePath(String clazz); boolean canRelocateClass(String clazz); /** * Replace the first class pattern match in the given string * @see #relocateAllClasses(String) */ String relocateClass(String input); String applyToSourceContent(String sourceContent); /** * Replace all class pattern matches in the given input. * @see #relocateClass(String) */ String relocateAllClasses(String input); } ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/relocation/SerializedLambdaRelocator.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.relocation; import java.util.List; import java.util.regex.Pattern; /** @author Kamil Wójcik */ public class SerializedLambdaRelocator extends SimpleRelocator { private final Pattern serializedLambdaDefinitionPattern = Pattern.compile("\\(([BCDFIJSZ]|\\[+[BCDFIJSZ]|\\[*L[^;]+;)*\\)([BCDFIJSZ]|V|\\[+[BCDFIJSZ]|\\[*L[^;]+;)"); private final Pattern clazzInsideFunctionDefintionPattern; private final String shadedPathPattern; private boolean shouldRelocate = true; public SerializedLambdaRelocator( String pattern, String shadedPattern, List includes, List excludes, boolean rawString) { super(pattern, shadedPattern, includes, excludes, rawString); if (shadedPattern != null && pattern != null) { this.shadedPathPattern = shadedPattern.replace('.', '/'); String pathPattern = pattern.replace('.', '/'); this.clazzInsideFunctionDefintionPattern = Pattern.compile("(?<=[(;)]L)" + Pattern.quote(pathPattern)); } else { this.clazzInsideFunctionDefintionPattern = null; this.shadedPathPattern = null; this.shouldRelocate = false; } } @Override public boolean canRelocatePath(String path) { return shouldRelocate && serializedLambdaDefinitionPattern.matcher(path).matches(); } @Override public boolean canRelocateClass(String clazz) { return false; } @Override public String relocatePath(String path) { return !shouldRelocate ? path : clazzInsideFunctionDefintionPattern.matcher(path).replaceAll(shadedPathPattern); } @Override public String relocateClass(String input) { return input; } @Override public String relocateAllClasses(String input) { return input; } @Override public String applyToSourceContent(String sourceContent) { return sourceContent; } } ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/relocation/SimpleRelocator.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.relocation; import java.util.Collection; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.codehaus.plexus.util.SelectorUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Jason van Zyl * @author Mauro Talevi */ public class SimpleRelocator implements Relocator { private static final Logger LOGGER = LoggerFactory.getLogger(SimpleRelocator.class); /** * Match dot, slash or space at end of string */ private static final Pattern RX_ENDS_WITH_DOT_SLASH_SPACE = Pattern.compile("[./ ]$"); /** * Match

    *
  • certain Java keywords + space
  • *
  • beginning of Javadoc link + optional line breaks and continuations with '*'
  • *
  • (opening curly brace / opening parenthesis / comma / equals / semicolon) + space
  • *
  • (closing curly brace / closing multi-line comment) + space
  • *
* at end of string */ private static final Pattern RX_ENDS_WITH_JAVA_KEYWORD = Pattern.compile( "\\b(import|package|public|protected|private|static|final|synchronized|abstract|volatile|extends|implements|throws) $" + "|" + "\\{@link( \\*)* $" + "|" + "([{}(=;,]|\\*/) $"); /** plain text, no wildcards, always refers to fully qualified package names, may be {@code null} when rawString is {@code true}. */ private final String originalPattern; /** plain text, no wildcards, always refers to paths with "/" separator, never {@code null}. */ private final String originalPathPattern; /** * May be {@code null} when {@link #rawString} is true */ private final Pattern regExPattern; private final Pattern regExPathPattern; /** * Replacement (no wildcards) for {@link #originalPattern}, may be {@code null} when {@link #rawString} is true. */ private final String shadedPattern; /** * Replacement (no wildcards) for {@link #originalPathPattern}. */ private final String shadedPathPattern; /** * Patterns to include in relocation. * Only Ant-based patterns (used with SelectorUtils.matchPath), must not start with "%ant[" prefix. Include both forms with dots and slashes, e.g. "my/package/**" and "my/package/*" for class patterns, "my/path/**" and "my/path/*" for path patterns. */ private final Set includes; /** * Patterns to exclude from relocation. * Only Ant-based patterns (used with SelectorUtils.matchPath), must not start with "%ant[" prefix. Include both forms with dots and slashes, e.g. "my/package/**" and "my/package/*" for class patterns, "my/path/**" and "my/path/*" for path patterns. */ private final Set excludes; // prefix (no wildcards), derived from excludes private final Set sourcePackageExcludes = new LinkedHashSet<>(); // prefix (no wildcards), derived from excludes private final Set sourcePathExcludes = new LinkedHashSet<>(); private final boolean rawString; /** * Same as {@link #SimpleRelocator(String, String, List, List, boolean)} with {@code rawString} set to {@code false}. * @param patt * @param shadedPattern * @param includes * @param excludes */ public SimpleRelocator(String patt, String shadedPattern, List includes, List excludes) { this(patt, shadedPattern, includes, excludes, false); } /** * Creates a relocator with the given patterns and includes/excludes. If {@code rawString} is {@code true}, then the given pattern is * treated as regular expression pattern, otherwise it is treated as plain text with no wildcards. * In the latter case, the pattern is expected to refer to classes, not paths, and the constructor will derive the path pattern by replacing dots with slashes. * @param pattern * @param shadedPattern * @param includes * @param excludes * @param rawString */ public SimpleRelocator( String pattern, String shadedPattern, List includes, List excludes, boolean rawString) { this.rawString = rawString; if (rawString) { originalPathPattern = pattern; this.shadedPathPattern = shadedPattern; originalPattern = null; // not used for raw string relocator this.shadedPattern = null; // not used for raw string relocator } else { if (pattern == null) { // means default package throw new IllegalArgumentException( "Pattern must not be null, otherwise it is unclear what to relocate!"); } else { originalPattern = pattern.replace('/', '.'); originalPathPattern = pattern.replace('.', '/'); } if (shadedPattern != null) { this.shadedPattern = shadedPattern.replace('/', '.'); this.shadedPathPattern = shadedPattern.replace('.', '/'); } else { this.shadedPattern = "hidden." + originalPattern; this.shadedPathPattern = "hidden/" + originalPathPattern; } } if (rawString) { if ((includes != null && !includes.isEmpty()) || (excludes != null && !excludes.isEmpty())) { LOGGER.warn("Includes and excludes are ignored when rawString is true"); } // In raw string mode, the pattern is treated as regular expression, so we compile it as is, without quoting // it. this.regExPattern = originalPattern != null ? Pattern.compile(originalPattern) : null; this.regExPathPattern = Pattern.compile(originalPathPattern); this.includes = null; this.excludes = null; } else { this.includes = normalizePatterns(includes); this.excludes = normalizePatterns(excludes); // Don't replace all dots to slashes, otherwise /META-INF/maven/${groupId} can't be matched. if (includes != null && !includes.isEmpty()) { this.includes.addAll(includes); } if (excludes != null && !excludes.isEmpty()) { this.excludes.addAll(excludes); } if (this.excludes != null) { // Create exclude pattern sets for sources for (String exclude : this.excludes) { // Excludes should be subpackages of the global pattern if (exclude.startsWith(originalPattern)) { sourcePackageExcludes.add( exclude.substring(originalPattern.length()).replaceFirst("[.][*]$", "")); } // Excludes should be subpackages of the global pattern if (exclude.startsWith(originalPathPattern)) { sourcePathExcludes.add( exclude.substring(originalPathPattern.length()).replaceFirst("[/][*]$", "")); } } } this.regExPattern = originalPattern != null ? Pattern.compile(Pattern.quote(originalPattern)) : null; this.regExPathPattern = Pattern.compile(Pattern.quote(originalPathPattern)); } } /** * Normalizes the given patterns by replacing dots with slashes and slashes with dots so that both forms are returned. * * @param patterns * @return the normalized patterns, or {@code null} if the given patterns were {@code null} or empty */ private static Set normalizePatterns(Collection patterns) { Set normalized = null; if (patterns != null && !patterns.isEmpty()) { normalized = new LinkedHashSet<>(); for (String pattern : patterns) { String classPattern = pattern.replace('.', '/'); normalized.add(classPattern); // Actually, class patterns should just use 'foo.bar.*' ending with a single asterisk, but some users // mistake them for path patterns like 'my/path/**', so let us be a bit more lenient here. if (classPattern.endsWith("/*") || classPattern.endsWith("/**")) { String packagePattern = classPattern.substring(0, classPattern.lastIndexOf('/')); normalized.add(packagePattern); } } } return normalized; } protected boolean isIncluded(String path) { if (includes != null && !includes.isEmpty()) { for (String include : includes) { if (SelectorUtils.matchPath(include, path, true)) { return true; } } return false; } return true; } protected boolean isExcluded(String path) { if (excludes != null && !excludes.isEmpty()) { for (String exclude : excludes) { if (SelectorUtils.matchPath(exclude, path, true)) { return true; } } } return false; } @Override public boolean canRelocatePath(String path) { if (rawString) { return regExPathPattern.matcher(path).find(); } if (path.endsWith(".class")) { path = path.substring(0, path.length() - 6); } // Allow for annoying option of an extra / on the front of a path. See MSHADE-119; comes from // getClass().getResource("/a/b/c.properties"). if (!path.isEmpty() && path.charAt(0) == '/') { path = path.substring(1); } if (isIncluded(path) && !isExcluded(path)) { Matcher matcher = regExPathPattern.matcher(path); if (matcher.find()) { return matcher.start() == 0; } } return false; } @Override public boolean canRelocateClass(String clazz) { return !rawString && clazz.indexOf('/') < 0 && canRelocatePath(clazz.replace('.', '/')); } @Override public String relocatePath(String path) { if (rawString) { return regExPathPattern.matcher(path).replaceAll(shadedPathPattern); } else { return regExPathPattern.matcher(path).replaceFirst(shadedPathPattern); } } @Override public String relocateClass(String input) { return regExPattern == null ? input : regExPattern.matcher(input).replaceFirst(shadedPattern); } @Override public String relocateAllClasses(String input) { return regExPattern == null ? input : regExPattern.matcher(input).replaceAll(shadedPattern); } @Override public String applyToSourceContent(String sourceContent) { if (rawString) { return sourceContent; } sourceContent = shadeSourceWithExcludes(sourceContent, originalPattern, shadedPattern, sourcePackageExcludes); return shadeSourceWithExcludes(sourceContent, originalPathPattern, shadedPathPattern, sourcePathExcludes); } private String shadeSourceWithExcludes( String sourceContent, String patternFrom, String patternTo, Set excludedPatterns) { // Usually shading makes package names a bit longer, so make buffer 10% bigger than original source StringBuilder shadedSourceContent = new StringBuilder(sourceContent.length() * 11 / 10); boolean isFirstSnippet = true; // Make sure that search pattern starts at word boundary and that we look for literal ".", not regex jokers String[] snippets = sourceContent.split("\\b" + patternFrom.replace(".", "[.]") + "\\b"); for (int i = 0, snippetsLength = snippets.length; i < snippetsLength; i++) { String snippet = snippets[i]; String previousSnippet = isFirstSnippet ? "" : snippets[i - 1]; boolean doExclude = false; for (String excludedPattern : excludedPatterns) { if (snippet.startsWith(excludedPattern)) { doExclude = true; break; } } if (isFirstSnippet) { shadedSourceContent.append(snippet); isFirstSnippet = false; } else { String previousSnippetOneLine = previousSnippet.replaceAll("\\s+", " "); boolean afterDotSlashSpace = RX_ENDS_WITH_DOT_SLASH_SPACE .matcher(previousSnippetOneLine) .find(); boolean afterJavaKeyWord = RX_ENDS_WITH_JAVA_KEYWORD .matcher(previousSnippetOneLine) .find(); boolean shouldExclude = doExclude || afterDotSlashSpace && !afterJavaKeyWord; shadedSourceContent .append(shouldExclude ? patternFrom : patternTo) .append(snippet); } } return shadedSourceContent.toString(); } } ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/resource/AbstractCompatibilityTransformer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.resource; import java.io.IOException; import java.io.InputStream; import java.util.List; import org.apache.maven.plugins.shade.relocation.Relocator; /** * An abstract class to implement once the old non-reproducible ResourceTransformer API. */ abstract class AbstractCompatibilityTransformer implements ReproducibleResourceTransformer { @Override public final void processResource(String resource, InputStream is, List relocators) throws IOException { processResource(resource, is, relocators, 0); } } ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/resource/ApacheLicenseResourceTransformer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.resource; import java.io.IOException; import java.io.InputStream; import java.util.List; import java.util.jar.JarOutputStream; import org.apache.maven.plugins.shade.relocation.Relocator; /** * Prevents duplicate copies of the license */ public class ApacheLicenseResourceTransformer extends AbstractCompatibilityTransformer { private static final String LICENSE_PATH = "META-INF/LICENSE"; private static final String LICENSE_TXT_PATH = "META-INF/LICENSE.txt"; private static final String LICENSE_MD_PATH = "META-INF/LICENSE.md"; @Override public boolean canTransformResource(String resource) { return LICENSE_PATH.equalsIgnoreCase(resource) || LICENSE_TXT_PATH.regionMatches(true, 0, resource, 0, LICENSE_TXT_PATH.length()) || LICENSE_MD_PATH.regionMatches(true, 0, resource, 0, LICENSE_MD_PATH.length()); } @Override public void processResource(String resource, InputStream is, List relocators, long time) throws IOException { // no op } @Override public boolean hasTransformedResource() { return false; } @Override public void modifyOutputStream(JarOutputStream os) throws IOException { // no op } } ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/resource/ApacheNoticeResourceTransformer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.resource; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.Writer; import java.text.SimpleDateFormat; import java.util.Date; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeSet; import java.util.jar.JarEntry; import java.util.jar.JarOutputStream; import org.apache.maven.plugins.shade.relocation.Relocator; /** * Merges META-INF/NOTICE.TXT files. */ public class ApacheNoticeResourceTransformer extends AbstractCompatibilityTransformer { Set entries = new LinkedHashSet<>(); Map> organizationEntries = new LinkedHashMap<>(); String projectName = ""; // MSHADE-101 :: NullPointerException when projectName is missing boolean addHeader = true; String preamble1 = "// ------------------------------------------------------------------\n" + "// NOTICE file corresponding to the section 4d of The Apache License,\n" + "// Version 2.0, in this case for "; String preamble2 = "\n// ------------------------------------------------------------------\n"; String preamble3 = "This product includes software developed at\n"; // defaults overridable via config in pom String organizationName = "The Apache Software Foundation"; String organizationURL = "http://www.apache.org/"; String inceptionYear = "2006"; String copyright; /** * The file encoding of the NOTICE file. */ String encoding; private long time = Long.MIN_VALUE; private static final String NOTICE_PATH = "META-INF/NOTICE"; private static final String NOTICE_TXT_PATH = "META-INF/NOTICE.txt"; private static final String NOTICE_MD_PATH = "META-INF/NOTICE.md"; @Override public boolean canTransformResource(String resource) { return NOTICE_PATH.equalsIgnoreCase(resource) || NOTICE_TXT_PATH.equalsIgnoreCase(resource) || NOTICE_MD_PATH.equalsIgnoreCase(resource); } @Override public void processResource(String resource, InputStream is, List relocators, long time) throws IOException { if (entries.isEmpty()) { String year = new SimpleDateFormat("yyyy").format(new Date()); if (!inceptionYear.equals(year)) { year = inceptionYear + "-" + year; } // add headers if (addHeader) { entries.add(preamble1 + projectName + preamble2); } else { entries.add(""); } // fake second entry, we'll look for a real one later entries.add(projectName + "\nCopyright " + year + " " + organizationName + "\n"); entries.add(preamble3 + organizationName + " (" + organizationURL + ").\n"); } BufferedReader reader; if (encoding != null && !encoding.isEmpty()) { reader = new BufferedReader(new InputStreamReader(is, encoding)); } else { reader = new BufferedReader(new InputStreamReader(is)); } String line = reader.readLine(); StringBuilder sb = new StringBuilder(); Set currentOrg = null; int lineCount = 0; while (line != null) { String trimedLine = line.trim(); if (!trimedLine.startsWith("//")) { if (trimedLine.length() > 0) { if (trimedLine.startsWith("- ")) { // resource-bundle 1.3 mode if (lineCount == 1 && sb.toString().contains("This product includes/uses software(s) developed by")) { currentOrg = organizationEntries.get(sb.toString().trim()); if (currentOrg == null) { currentOrg = new TreeSet<>(); organizationEntries.put(sb.toString().trim(), currentOrg); } sb = new StringBuilder(); } else if (sb.length() > 0 && currentOrg != null) { currentOrg.add(sb.toString()); sb = new StringBuilder(); } } sb.append(line).append("\n"); lineCount++; } else { String ent = sb.toString(); if (ent.startsWith(projectName) && ent.contains("Copyright ")) { copyright = ent; } if (currentOrg == null) { entries.add(ent); } else { currentOrg.add(ent); } sb = new StringBuilder(); lineCount = 0; currentOrg = null; } } line = reader.readLine(); } if (sb.length() > 0) { if (currentOrg == null) { entries.add(sb.toString()); } else { currentOrg.add(sb.toString()); } } if (time > this.time) { this.time = time; } } @Override public boolean hasTransformedResource() { return true; } @Override public void modifyOutputStream(JarOutputStream jos) throws IOException { JarEntry jarEntry = new JarEntry(NOTICE_PATH); jarEntry.setTime(time); jos.putNextEntry(jarEntry); Writer writer; if (encoding != null && !encoding.isEmpty()) { writer = new OutputStreamWriter(jos, encoding); } else { writer = new OutputStreamWriter(jos); } int count = 0; for (String line : entries) { ++count; if (line.equals(copyright) && count != 2) { continue; } if (count == 2 && copyright != null) { writer.write(copyright); writer.write('\n'); } else { writer.write(line); writer.write('\n'); } if (count == 3) { // do org stuff for (Map.Entry> entry : organizationEntries.entrySet()) { writer.write(entry.getKey()); writer.write('\n'); for (String l : entry.getValue()) { writer.write(l); } writer.write('\n'); } } } writer.flush(); entries.clear(); } } ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/resource/AppendingTransformer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.resource; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.List; import java.util.jar.JarEntry; import java.util.jar.JarOutputStream; import org.apache.maven.plugins.shade.relocation.Relocator; import org.codehaus.plexus.util.IOUtil; /** * A resource processor that appends content for a resource, separated by a newline. */ public class AppendingTransformer extends AbstractCompatibilityTransformer { String resource; ByteArrayOutputStream data = new ByteArrayOutputStream(); private long time = Long.MIN_VALUE; @Override public boolean canTransformResource(String r) { return resource != null && resource.equalsIgnoreCase(r); } @Override public void processResource(String resource, InputStream is, List relocators, long time) throws IOException { IOUtil.copy(is, data); data.write('\n'); if (time > this.time) { this.time = time; } } @Override public boolean hasTransformedResource() { return data.size() > 0; } @Override public void modifyOutputStream(JarOutputStream jos) throws IOException { JarEntry jarEntry = new JarEntry(resource); jarEntry.setTime(time); jos.putNextEntry(jarEntry); jos.write(data.toByteArray()); data.reset(); } } ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/resource/ComponentsXmlResourceTransformer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.resource; import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.Reader; import java.io.Writer; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.jar.JarEntry; import java.util.jar.JarOutputStream; import org.apache.maven.plugins.shade.relocation.Relocator; import org.codehaus.plexus.util.ReaderFactory; import org.codehaus.plexus.util.WriterFactory; import org.codehaus.plexus.util.xml.Xpp3Dom; import org.codehaus.plexus.util.xml.Xpp3DomBuilder; import org.codehaus.plexus.util.xml.Xpp3DomWriter; /** * A resource processor that aggregates plexus components.xml files. */ public class ComponentsXmlResourceTransformer extends AbstractCompatibilityTransformer { private Map components = new LinkedHashMap<>(); private long time = Long.MIN_VALUE; public static final String COMPONENTS_XML_PATH = "META-INF/plexus/components.xml"; @Override public boolean canTransformResource(String resource) { return COMPONENTS_XML_PATH.equals(resource); } @Override public void processResource(String resource, InputStream is, List relocators, long time) throws IOException { Xpp3Dom newDom; try { BufferedInputStream bis = new BufferedInputStream(is) { @Override public void close() throws IOException { // leave ZIP open } }; Reader reader = ReaderFactory.newXmlReader(bis); newDom = Xpp3DomBuilder.build(reader); } catch (Exception e) { throw new IOException("Error parsing components.xml in " + is, e); } // Only try to merge in components if there are some elements in the component-set if (newDom.getChild("components") == null) { return; } Xpp3Dom[] children = newDom.getChild("components").getChildren("component"); for (Xpp3Dom component : children) { String role = getValue(component, "role"); role = getRelocatedClass(role, relocators); setValue(component, "role", role); String roleHint = getValue(component, "role-hint"); String impl = getValue(component, "implementation"); impl = getRelocatedClass(impl, relocators); setValue(component, "implementation", impl); String key = role + ':' + roleHint; if (components.containsKey(key)) { // TODO: use the tools in Plexus to merge these properly. For now, I just need an all-or-nothing // configuration carry over Xpp3Dom dom = components.get(key); if (dom.getChild("configuration") != null) { component.addChild(dom.getChild("configuration")); } } Xpp3Dom requirements = component.getChild("requirements"); if (requirements != null && requirements.getChildCount() > 0) { for (int r = requirements.getChildCount() - 1; r >= 0; r--) { Xpp3Dom requirement = requirements.getChild(r); String requiredRole = getValue(requirement, "role"); requiredRole = getRelocatedClass(requiredRole, relocators); setValue(requirement, "role", requiredRole); } } components.put(key, component); } if (time > this.time) { this.time = time; } } @Override public void modifyOutputStream(JarOutputStream jos) throws IOException { JarEntry jarEntry = new JarEntry(COMPONENTS_XML_PATH); jarEntry.setTime(time); byte[] data = getTransformedResource(); jos.putNextEntry(jarEntry); jos.write(data); components.clear(); } @Override public boolean hasTransformedResource() { return !components.isEmpty(); } byte[] getTransformedResource() throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(1024 * 4); try (Writer writer = WriterFactory.newXmlWriter(baos)) { Xpp3Dom dom = new Xpp3Dom("component-set"); Xpp3Dom componentDom = new Xpp3Dom("components"); dom.addChild(componentDom); for (Xpp3Dom component : components.values()) { componentDom.addChild(component); } Xpp3DomWriter.write(writer, dom); } return baos.toByteArray(); } private String getRelocatedClass(String className, List relocators) { if (className != null && className.length() > 0 && relocators != null) { for (Relocator relocator : relocators) { if (relocator.canRelocateClass(className)) { return relocator.relocateClass(className); } } } return className; } private static String getValue(Xpp3Dom dom, String element) { Xpp3Dom child = dom.getChild(element); return (child != null && child.getValue() != null) ? child.getValue() : ""; } private static void setValue(Xpp3Dom dom, String element, String value) { Xpp3Dom child = dom.getChild(element); if (child == null || value == null || value.length() <= 0) { return; } child.setValue(value); } } ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/resource/DontIncludeResourceTransformer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.resource; import java.io.IOException; import java.io.InputStream; import java.util.List; import java.util.jar.JarOutputStream; import org.apache.maven.plugins.shade.relocation.Relocator; /** * A resource processor that prevents the inclusion of an arbitrary * resource into the shaded JAR. */ public class DontIncludeResourceTransformer extends AbstractCompatibilityTransformer { String resource; List resources; @Override public boolean canTransformResource(String r) { if ((resource != null && !resource.isEmpty()) && r.endsWith(resource)) { return true; } if (resources != null) { for (String resourceEnd : resources) { if (r.endsWith(resourceEnd)) { return true; } } } return false; } @Override public void processResource(String resource, InputStream is, List relocators, long time) throws IOException { // no op } @Override public boolean hasTransformedResource() { return false; } @Override public void modifyOutputStream(JarOutputStream os) throws IOException { // no op } } ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/resource/GroovyResourceTransformer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.resource; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Properties; import java.util.jar.JarEntry; import java.util.jar.JarOutputStream; import org.apache.maven.plugins.shade.relocation.Relocator; /** * Aggregate Apache Groovy extension modules descriptors */ public class GroovyResourceTransformer extends AbstractCompatibilityTransformer { static final String EXT_MODULE_NAME_LEGACY = "META-INF/services/org.codehaus.groovy.runtime.ExtensionModule"; // Since Groovy 2.5.x/Java 9 META-INF/services may only be used by Service Providers static final String EXT_MODULE_NAME = "META-INF/groovy/org.codehaus.groovy.runtime.ExtensionModule"; private List extensionClassesList = new ArrayList<>(); private List staticExtensionClassesList = new ArrayList<>(); private String extModuleName = "no-module-name"; private String extModuleVersion = "1.0"; private long time = Long.MIN_VALUE; @Override public boolean canTransformResource(String resource) { return EXT_MODULE_NAME.equals(resource) || EXT_MODULE_NAME_LEGACY.equals(resource); } @Override public void processResource(String resource, InputStream is, List relocators, long time) throws IOException { Properties out = new Properties(); try (InputStream props = is) { out.load(props); } String extensionClasses = out.getProperty("extensionClasses", "").trim(); if (extensionClasses.length() > 0) { append(extensionClasses, extensionClassesList); } String staticExtensionClasses = out.getProperty("staticExtensionClasses", "").trim(); if (staticExtensionClasses.length() > 0) { append(staticExtensionClasses, staticExtensionClassesList); } if (time > this.time) { this.time = time; } } private void append(String entry, List list) { if (entry != null) { Collections.addAll(list, entry.split("\\s*,\\s*")); } } @Override public boolean hasTransformedResource() { return extensionClassesList.size() > 0 && staticExtensionClassesList.size() > 0; } @Override public void modifyOutputStream(JarOutputStream os) throws IOException { if (hasTransformedResource()) { JarEntry jarEntry = new JarEntry(EXT_MODULE_NAME); jarEntry.setTime(time); os.putNextEntry(jarEntry); Properties desc = new Properties(); desc.put("moduleName", extModuleName); desc.put("moduleVersion", extModuleVersion); if (extensionClassesList.size() > 0) { desc.put("extensionClasses", join(extensionClassesList)); } if (staticExtensionClassesList.size() > 0) { desc.put("staticExtensionClasses", join(staticExtensionClassesList)); } desc.store(os, null); } } private String join(Collection strings) { Iterator it = strings.iterator(); switch (strings.size()) { case 0: return ""; case 1: return it.next(); default: StringBuilder buff = new StringBuilder(it.next()); while (it.hasNext()) { buff.append(",").append(it.next()); } return buff.toString(); } } public void setExtModuleName(String extModuleName) { this.extModuleName = extModuleName; } public void setExtModuleVersion(String extModuleVersion) { this.extModuleVersion = extModuleVersion; } } ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/resource/IncludeResourceTransformer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.resource; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.List; import java.util.jar.JarEntry; import java.util.jar.JarOutputStream; import org.apache.maven.plugins.shade.relocation.Relocator; import org.codehaus.plexus.util.IOUtil; /** * A resource processor that allows the addition of an arbitrary file * content into the shaded JAR. */ public class IncludeResourceTransformer extends AbstractCompatibilityTransformer { File file; String resource; private long time = Long.MIN_VALUE; @Override public boolean canTransformResource(String r) { return false; } @Override public void processResource(String resource, InputStream is, List relocators, long time) throws IOException { if (time > this.time) { this.time = time; } } @Override public boolean hasTransformedResource() { return file != null && file.exists(); } @Override public void modifyOutputStream(JarOutputStream jos) throws IOException { JarEntry jarEntry = new JarEntry(resource); jarEntry.setTime(time); try (InputStream in = new FileInputStream(file)) { jos.putNextEntry(jarEntry); IOUtil.copy(in, jos); } } @Override public String toString() { return "IncludeResourceTransformer {resource: '" + resource + "'}"; } } ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/resource/ManifestResourceTransformer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.resource; import java.io.IOException; import java.io.InputStream; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.jar.Attributes; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.jar.JarOutputStream; import java.util.jar.Manifest; import org.apache.maven.plugins.shade.relocation.Relocator; /** * A resource processor that allows the arbitrary addition of attributes to * the first MANIFEST.MF that is found in the set of JARs being processed, or * to a newly created manifest for the shaded JAR. * * @author Jason van Zyl * @since 1.2 */ public class ManifestResourceTransformer extends AbstractCompatibilityTransformer { private final List defaultAttributes = Arrays.asList("Export-Package", "Import-Package", "Provide-Capability", "Require-Capability"); // Configuration private String mainClass; private Map manifestEntries; private List additionalAttributes; // Fields private boolean manifestDiscovered; private Manifest manifest; private long time = Long.MIN_VALUE; private String shade; public void setMainClass(String mainClass) { this.mainClass = mainClass; } public void setManifestEntries(Map manifestEntries) { this.manifestEntries = manifestEntries; } public void setAdditionalAttributes(List additionalAttributes) { this.additionalAttributes = additionalAttributes; } @Override public boolean canTransformResource(String resource) { return JarFile.MANIFEST_NAME.equalsIgnoreCase(resource); } @Override public void processResource(String resource, InputStream is, List relocators, long time) throws IOException { // We just want to take the first manifest we come across as that's our project's manifest. This is the behavior // now which is situational at best. Right now there is no context passed in with the processing so we cannot // tell what artifact is being processed. if (!manifestDiscovered) { manifest = new Manifest(is); if (relocators != null && !relocators.isEmpty()) { final Attributes attributes = manifest.getMainAttributes(); for (final String attribute : defaultAttributes) { final String attributeValue = attributes.getValue(attribute); if (attributeValue != null) { String newValue = relocate(attributeValue, relocators); attributes.putValue(attribute, newValue); } } if (additionalAttributes != null) { for (final String attribute : additionalAttributes) { final String attributeValue = attributes.getValue(attribute); if (attributeValue != null) { String newValue = relocate(attributeValue, relocators); attributes.putValue(attribute, newValue); } } } } manifestDiscovered = true; if (time > this.time) { this.time = time; } } } @Override public boolean hasTransformedResource() { return true; } @Override public void modifyOutputStream(JarOutputStream jos) throws IOException { // If we didn't find a manifest, then let's create one. if (manifest == null) { manifest = new Manifest(); } Attributes attributes = manifest.getMainAttributes(); if (mainClass != null) { attributes.put(Attributes.Name.MAIN_CLASS, mainClass); } if (manifestEntries != null) { for (Map.Entry entry : manifestEntries.entrySet()) { if (entry.getValue() == null) { attributes.remove(new Attributes.Name(entry.getKey())); } else { attributes.put(new Attributes.Name(entry.getKey()), entry.getValue()); } } } JarEntry jarEntry = new JarEntry(JarFile.MANIFEST_NAME); jarEntry.setTime(time); jos.putNextEntry(jarEntry); manifest.write(jos); } private String relocate(String originalValue, List relocators) { String newValue = originalValue; for (Relocator relocator : relocators) { newValue = relocator.relocateAllClasses(newValue); } return newValue; } /** * The shades to apply this transformer to or no shades if no filter is applied. * * @param shade {@code null}, {@code jar}, {@code test-jar}, {@code sources-jar} or {@code test-sources-jar}. */ public void setForShade(String shade) { this.shade = shade; } public boolean isForShade(String shade) { return isUsedForDefaultShading() || this.shade.equalsIgnoreCase(shade); } public boolean isUsedForDefaultShading() { return this.shade == null || this.shade.isEmpty(); } } ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/resource/PluginXmlResourceTransformer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.resource; import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.Reader; import java.io.Writer; import java.util.ArrayList; import java.util.List; import java.util.jar.JarEntry; import java.util.jar.JarOutputStream; import org.apache.maven.plugins.shade.relocation.Relocator; import org.codehaus.plexus.util.ReaderFactory; import org.codehaus.plexus.util.WriterFactory; import org.codehaus.plexus.util.xml.Xpp3Dom; import org.codehaus.plexus.util.xml.Xpp3DomBuilder; import org.codehaus.plexus.util.xml.Xpp3DomWriter; /** * A resource processor that aggregates Maven plugin.xml files. * * @author Robert Scholte * @since 3.0 */ public class PluginXmlResourceTransformer extends AbstractCompatibilityTransformer { private List mojos = new ArrayList<>(); private long time = Long.MIN_VALUE; public static final String PLUGIN_XML_PATH = "META-INF/maven/plugin.xml"; @Override public boolean canTransformResource(String resource) { return PLUGIN_XML_PATH.equals(resource); } @Override public void processResource(String resource, InputStream is, List relocators, long time) throws IOException { Xpp3Dom newDom; try { BufferedInputStream bis = new BufferedInputStream(is) { @Override public void close() throws IOException { // leave ZIP open } }; Reader reader = ReaderFactory.newXmlReader(bis); newDom = Xpp3DomBuilder.build(reader); } catch (Exception e) { throw new IOException("Error parsing plugin.xml in " + is, e); } // Only try to merge in mojos if there are some elements in the plugin if (newDom.getChild("mojos") == null) { return; } if (time > this.time) { this.time = time; } for (Xpp3Dom mojo : newDom.getChild("mojos").getChildren("mojo")) { String impl = getValue(mojo, "implementation"); impl = getRelocatedClass(impl, relocators); setValue(mojo, "implementation", impl); Xpp3Dom parameters = mojo.getChild("parameters"); if (parameters != null) { for (Xpp3Dom parameter : parameters.getChildren()) { String type = getValue(parameter, "type"); type = getRelocatedClass(type, relocators); setValue(parameter, "type", type); } } Xpp3Dom configuration = mojo.getChild("configuration"); if (configuration != null) { for (Xpp3Dom configurationEntry : configuration.getChildren()) { String implementation = getAttribute(configurationEntry, "implementation"); implementation = getRelocatedClass(implementation, relocators); setAttribute(configurationEntry, "implementation", implementation); } } Xpp3Dom requirements = mojo.getChild("requirements"); if (requirements != null && requirements.getChildCount() > 0) { for (Xpp3Dom requirement : requirements.getChildren()) { String requiredRole = getValue(requirement, "role"); requiredRole = getRelocatedClass(requiredRole, relocators); setValue(requirement, "role", requiredRole); } } mojos.add(mojo); } } @Override public void modifyOutputStream(JarOutputStream jos) throws IOException { byte[] data = getTransformedResource(); JarEntry jarEntry = new JarEntry(PLUGIN_XML_PATH); jarEntry.setTime(time); jos.putNextEntry(jarEntry); jos.write(data); mojos.clear(); } @Override public boolean hasTransformedResource() { return !mojos.isEmpty(); } byte[] getTransformedResource() throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(1024 * 4); try (Writer writer = WriterFactory.newXmlWriter(baos)) { Xpp3Dom dom = new Xpp3Dom("plugin"); Xpp3Dom componentDom = new Xpp3Dom("mojos"); dom.addChild(componentDom); for (Xpp3Dom mojo : mojos) { componentDom.addChild(mojo); } Xpp3DomWriter.write(writer, dom); } return baos.toByteArray(); } private String getRelocatedClass(String className, List relocators) { if (className != null && className.length() > 0 && relocators != null) { for (Relocator relocator : relocators) { if (relocator.canRelocateClass(className)) { return relocator.relocateClass(className); } } } return className; } private static String getValue(Xpp3Dom dom, String element) { Xpp3Dom child = dom.getChild(element); return (child != null && child.getValue() != null) ? child.getValue() : ""; } private static void setValue(Xpp3Dom dom, String element, String value) { Xpp3Dom child = dom.getChild(element); if (child == null || value == null || value.length() <= 0) { return; } child.setValue(value); } private static String getAttribute(Xpp3Dom dom, String attribute) { return (dom.getAttribute(attribute) != null) ? dom.getAttribute(attribute) : ""; } private static void setAttribute(Xpp3Dom dom, String attribute, String value) { String attr = dom.getAttribute(attribute); if (attr == null || value == null || value.length() <= 0) { return; } dom.setAttribute(attribute, value); } } ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/resource/ReproducibleResourceTransformer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.resource; import java.io.IOException; import java.io.InputStream; import java.util.List; import org.apache.maven.plugins.shade.relocation.Relocator; /** * Transform resource ensuring reproducible output: that requires to get the timestamp of * the initial resources to define in a reproducible way the timestamp of the transformed * resource. * * @author Hervé Boutemy * @since 3.2.4 */ public interface ReproducibleResourceTransformer extends ResourceTransformer { /** * Transform an individual resource * @param resource The resource name * @param is An input stream for the resource, the implementation should *not* close this stream * @param relocators A list of relocators * @param time the time of the resource to process * @throws IOException When the IO blows up */ void processResource(String resource, InputStream is, List relocators, long time) throws IOException; } ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/resource/ResourceBundleAppendingTransformer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.resource; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.jar.JarEntry; import java.util.jar.JarOutputStream; import java.util.regex.Pattern; import org.apache.maven.plugins.shade.relocation.Relocator; import org.codehaus.plexus.util.IOUtil; /** * An appending transformer for resource bundles * * @author Robert Scholte * @since 3.0.0 */ public class ResourceBundleAppendingTransformer extends AbstractCompatibilityTransformer { private Map dataMap = new HashMap<>(); private Pattern resourceBundlePattern; private long time = Long.MIN_VALUE; /** * the base name of the resource bundle, a fully qualified class name * @param basename The basename. */ public void setBasename(String basename) { resourceBundlePattern = Pattern.compile(basename + "(_[a-zA-Z]+){0,3}\\.properties"); } @Override public boolean canTransformResource(String r) { return resourceBundlePattern != null && resourceBundlePattern.matcher(r).matches(); } @Override public void processResource(String resource, InputStream is, List relocators, long time) throws IOException { ByteArrayOutputStream data = dataMap.get(resource); if (data == null) { data = new ByteArrayOutputStream(); dataMap.put(resource, data); } IOUtil.copy(is, data); data.write('\n'); if (time > this.time) { this.time = time; } } @Override public boolean hasTransformedResource() { return !dataMap.isEmpty(); } @Override public void modifyOutputStream(JarOutputStream jos) throws IOException { for (Map.Entry dataEntry : dataMap.entrySet()) { JarEntry jarEntry = new JarEntry(dataEntry.getKey()); jarEntry.setTime(time); jos.putNextEntry(jarEntry); jos.write(dataEntry.getValue().toByteArray()); dataEntry.getValue().reset(); } } } ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/resource/ResourceTransformer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.resource; import java.io.IOException; import java.io.InputStream; import java.util.List; import java.util.jar.JarOutputStream; import org.apache.maven.plugins.shade.relocation.Relocator; /** @author Jason van Zyl */ public interface ResourceTransformer { boolean canTransformResource(String resource); /** * Transform an individual resource * @param resource The resource name * @param is An input stream for the resource, the implementation should *not* close this stream * @param relocators A list of relocators * @throws IOException When the IO blows up * @deprecated prefer ReproducibleResourceTransformer */ void processResource(String resource, InputStream is, List relocators) throws IOException; boolean hasTransformedResource(); void modifyOutputStream(JarOutputStream os) throws IOException; } ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/resource/ServicesResourceTransformer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.resource; import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Scanner; import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarOutputStream; import org.apache.maven.plugins.shade.relocation.Relocator; import org.codehaus.plexus.util.IOUtil; /** * Resources transformer that relocates classes in META-INF/services and appends entries in META-INF/services resources * into a single resource. For example, if there are several META-INF/services/org.apache.maven.project.ProjectBuilder * resources spread across many JARs the individual entries will all be concatenated into a single * META-INF/services/org.apache.maven.project.ProjectBuilder resource packaged into the resultant JAR produced by the * shading process. */ public class ServicesResourceTransformer extends AbstractCompatibilityTransformer { private static final String SERVICES_PATH = "META-INF/services"; private final Map> serviceEntries = new HashMap<>(); private long time = Long.MIN_VALUE; @Override public boolean canTransformResource(String resource) { return resource.startsWith(SERVICES_PATH); } @Override public void processResource(String resource, InputStream is, final List relocators, long time) throws IOException { resource = resource.substring(SERVICES_PATH.length() + 1); for (Relocator relocator : relocators) { if (relocator.canRelocateClass(resource)) { resource = relocator.relocateClass(resource); break; } } resource = SERVICES_PATH + '/' + resource; Set out = serviceEntries.computeIfAbsent(resource, k -> new LinkedHashSet<>()); Scanner scanner = new Scanner(is, StandardCharsets.UTF_8.name()); while (scanner.hasNextLine()) { String relContent = scanner.nextLine(); for (Relocator relocator : relocators) { if (relocator.canRelocateClass(relContent)) { relContent = relocator.applyToSourceContent(relContent); } } out.add(relContent); } if (time > this.time) { this.time = time; } } @Override public boolean hasTransformedResource() { return !serviceEntries.isEmpty(); } @Override public void modifyOutputStream(JarOutputStream jos) throws IOException { for (Map.Entry> entry : serviceEntries.entrySet()) { String key = entry.getKey(); Set data = entry.getValue(); JarEntry jarEntry = new JarEntry(key); jarEntry.setTime(time); jos.putNextEntry(jarEntry); IOUtil.copy((String.join("\n", data) + "\n").getBytes(StandardCharsets.UTF_8), jos); jos.flush(); data.clear(); } } } ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/resource/SisuIndexResourceTransformer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.resource; import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; import java.util.Scanner; import java.util.jar.JarEntry; import java.util.jar.JarOutputStream; import org.apache.maven.plugins.shade.relocation.Relocator; import org.codehaus.plexus.util.IOUtil; /** * Resource transformer that relocates classes in {@code META-INF/sisu/javax.inject.Named} and appends resources * into a single resource. * * @since 3.3.0 */ public class SisuIndexResourceTransformer extends AbstractCompatibilityTransformer { private static final String SISU_INDEX_PATH = "META-INF/sisu/javax.inject.Named"; private final ArrayList indexEntries = new ArrayList<>(); private long time = Long.MIN_VALUE; @Override public boolean canTransformResource(final String resource) { return resource.equals(SISU_INDEX_PATH); } @Override public void processResource( final String resource, final InputStream is, final List relocators, long time) throws IOException { Scanner scanner = new Scanner(is, StandardCharsets.UTF_8.name()); while (scanner.hasNextLine()) { String relContent = scanner.nextLine(); for (Relocator relocator : relocators) { if (relocator.canRelocateClass(relContent)) { relContent = relocator.applyToSourceContent(relContent); } } indexEntries.add(relContent); } if (time > this.time) { this.time = time; } } @Override public boolean hasTransformedResource() { return !indexEntries.isEmpty(); } @Override public void modifyOutputStream(final JarOutputStream jos) throws IOException { JarEntry jarEntry = new JarEntry(SISU_INDEX_PATH); jarEntry.setTime(time); jos.putNextEntry(jarEntry); IOUtil.copy((String.join("\n", indexEntries) + "\n").getBytes(StandardCharsets.UTF_8), jos); jos.flush(); indexEntries.clear(); } } ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/resource/UseDependencyReducedPom.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.resource; import java.io.File; import java.util.ArrayList; import java.util.List; import org.apache.maven.project.MavenProject; /** * Manually creates the resource processors needed to remove the original pom.xml and inject * the dependency-reduced-pom.xml in its place in the shaded JAR. */ public class UseDependencyReducedPom { public static List createPomReplaceTransformers( MavenProject project, File dependencyReducedPomLocation) { String pomInFinalJarFilename = "META-INF/maven/" + project.getGroupId() + "/" + project.getArtifactId() + "/pom.xml"; List resourceTransformers = new ArrayList<>(); DontIncludeResourceTransformer removePom = new DontIncludeResourceTransformer(); removePom.resource = pomInFinalJarFilename; resourceTransformers.add(removePom); IncludeResourceTransformer insertDependencyReducedPom = new IncludeResourceTransformer(); insertDependencyReducedPom.file = dependencyReducedPomLocation; insertDependencyReducedPom.resource = pomInFinalJarFilename; resourceTransformers.add(insertDependencyReducedPom); return resourceTransformers; } } ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/resource/XmlAppendingTransformer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.resource; import java.io.IOException; import java.io.InputStream; import java.io.StringReader; import java.util.Iterator; import java.util.List; import java.util.jar.JarEntry; import java.util.jar.JarOutputStream; import org.apache.maven.plugins.shade.relocation.Relocator; import org.jdom2.Attribute; import org.jdom2.Content; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.JDOMException; import org.jdom2.input.SAXBuilder; import org.jdom2.output.Format; import org.jdom2.output.XMLOutputter; import org.xml.sax.EntityResolver; import org.xml.sax.InputSource; import org.xml.sax.SAXException; /** * Appends multiple occurrences of some XML file. */ public class XmlAppendingTransformer extends AbstractCompatibilityTransformer { public static final String XSI_NS = "http://www.w3.org/2001/XMLSchema-instance"; boolean ignoreDtd = true; String resource; Document doc; private long time = Long.MIN_VALUE; @Override public boolean canTransformResource(String r) { return resource != null && resource.equalsIgnoreCase(r); } @Override public void processResource(String resource, InputStream is, List relocators, long time) throws IOException { Document r; try { SAXBuilder builder = new SAXBuilder(false); builder.setExpandEntities(false); if (ignoreDtd) { builder.setEntityResolver(new EntityResolver() { @Override public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException { return new InputSource(new StringReader("")); } }); } r = builder.build(is); } catch (JDOMException e) { throw new RuntimeException("Error processing resource " + resource + ": " + e.getMessage(), e); } if (doc == null) { doc = r; } else { Element root = r.getRootElement(); for (Iterator itr = root.getAttributes().iterator(); itr.hasNext(); ) { Attribute a = itr.next(); itr.remove(); Element mergedEl = doc.getRootElement(); Attribute mergedAtt = mergedEl.getAttribute(a.getName(), a.getNamespace()); if (mergedAtt == null) { mergedEl.setAttribute(a); } } for (Iterator itr = root.getChildren().iterator(); itr.hasNext(); ) { Content n = itr.next(); itr.remove(); doc.getRootElement().addContent(n); } } if (time > this.time) { this.time = time; } } @Override public boolean hasTransformedResource() { return doc != null; } @Override public void modifyOutputStream(JarOutputStream jos) throws IOException { JarEntry jarEntry = new JarEntry(resource); jarEntry.setTime(time); jos.putNextEntry(jarEntry); new XMLOutputter(Format.getPrettyFormat()).output(doc, jos); doc = null; } } ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/resource/properties/MicroprofileConfigTransformer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.resource.properties; /** * Enables to merge Microprofile Config configuration files properly respecting their ordinal. * * @since 3.2.2 */ public class MicroprofileConfigTransformer extends PropertiesTransformer { public MicroprofileConfigTransformer() { super(null, "config_ordinal", 1000, false); } } ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/resource/properties/OpenWebBeansPropertiesTransformer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.resource.properties; /** * Enables to merge openwebbeans configuration files properly respecting their ordinal. * * @since 3.2.2 */ public class OpenWebBeansPropertiesTransformer extends PropertiesTransformer { public OpenWebBeansPropertiesTransformer() { super("META-INF/openwebbeans/openwebbeans.properties", "configuration.ordinal", 100, false); } } ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/resource/properties/PropertiesTransformer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.resource.properties; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStream; import java.io.OutputStreamWriter; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.Properties; import java.util.jar.JarEntry; import java.util.jar.JarOutputStream; import org.apache.maven.plugins.shade.relocation.Relocator; import org.apache.maven.plugins.shade.resource.ReproducibleResourceTransformer; import org.apache.maven.plugins.shade.resource.properties.io.NoCloseOutputStream; import org.apache.maven.plugins.shade.resource.properties.io.SkipPropertiesDateLineWriter; /** * Enables to merge a set of properties respecting priority between them. * * @since 3.2.2 */ public class PropertiesTransformer implements ReproducibleResourceTransformer { private String resource; private String alreadyMergedKey; private String ordinalKey; private int defaultOrdinal; private boolean reverseOrder; private long time = Long.MIN_VALUE; private final List properties = new ArrayList<>(); public PropertiesTransformer() { // no-op } protected PropertiesTransformer( final String resource, final String ordinalKey, final int defaultOrdinal, final boolean reversed) { this.resource = resource; this.ordinalKey = ordinalKey; this.defaultOrdinal = defaultOrdinal; this.reverseOrder = reversed; } @Override public boolean canTransformResource(final String resource) { return Objects.equals(resource, this.resource); } @Override public final void processResource(String resource, InputStream is, List relocators) throws IOException { processResource(resource, is, relocators, 0); } @Override public void processResource( final String resource, final InputStream is, final List relocators, long time) throws IOException { final Properties p = new Properties(); p.load(is); properties.add(p); if (time > this.time) { this.time = time; } } @Override public boolean hasTransformedResource() { return !properties.isEmpty(); } @Override public void modifyOutputStream(JarOutputStream os) throws IOException { if (properties.isEmpty()) { return; } final Properties out = mergeProperties(sortProperties()); if (ordinalKey != null) { out.remove(ordinalKey); } if (alreadyMergedKey != null) { out.remove(alreadyMergedKey); } JarEntry jarEntry = new JarEntry(resource); jarEntry.setTime(time); os.putNextEntry(jarEntry); final BufferedWriter writer = new SkipPropertiesDateLineWriter( new OutputStreamWriter(new NoCloseOutputStream(os), StandardCharsets.ISO_8859_1)); out.store(writer, " Merged by maven-shade-plugin (" + getClass().getName() + ")"); writer.close(); os.closeEntry(); } public void setReverseOrder(final boolean reverseOrder) { this.reverseOrder = reverseOrder; } public void setResource(final String resource) { this.resource = resource; } public void setOrdinalKey(final String ordinalKey) { this.ordinalKey = ordinalKey; } public void setDefaultOrdinal(final int defaultOrdinal) { this.defaultOrdinal = defaultOrdinal; } public void setAlreadyMergedKey(final String alreadyMergedKey) { this.alreadyMergedKey = alreadyMergedKey; } private List sortProperties() { final List sortedProperties = new ArrayList<>(); boolean foundMaster = false; for (final Properties current : properties) { if (alreadyMergedKey != null) { final String master = current.getProperty(alreadyMergedKey); if (Boolean.parseBoolean(master)) { if (foundMaster) { throw new IllegalStateException( "Ambiguous merged values: " + sortedProperties + ", " + current); } foundMaster = true; sortedProperties.clear(); sortedProperties.add(current); } } if (!foundMaster) { final int configOrder = getConfigurationOrdinal(current); int i; for (i = 0; i < sortedProperties.size(); i++) { int listConfigOrder = getConfigurationOrdinal(sortedProperties.get(i)); if ((!reverseOrder && listConfigOrder > configOrder) || (reverseOrder && listConfigOrder < configOrder)) { break; } } sortedProperties.add(i, current); } } return sortedProperties; } private int getConfigurationOrdinal(final Properties p) { if (ordinalKey == null) { return defaultOrdinal; } final String configOrderString = p.getProperty(ordinalKey); if (configOrderString != null && configOrderString.length() > 0) { return Integer.parseInt(configOrderString); } return defaultOrdinal; } private static Properties mergeProperties(final List sortedProperties) { final Properties mergedProperties = new SortedProperties(); for (final Properties p : sortedProperties) { mergedProperties.putAll(p); } return mergedProperties; } } ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/resource/properties/SortedProperties.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.resource.properties; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Enumeration; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; /** * Internal Properties instance sorting its keys on iterations for store() usages. * It ensures properties persistence is deterministic. * * IMPORTANT: this only overrides methods used across JVM in store() so ordering is not guaranteed for other cases. */ public class SortedProperties extends Properties { @Override public Set> entrySet() { final List> entries = new ArrayList<>(super.entrySet()); Collections.sort(entries, new Comparator>() { @Override public int compare(Map.Entry o1, Map.Entry o2) { return String.valueOf(o1.getKey()).compareTo(String.valueOf(o2.getKey())); } }); return new LinkedHashSet<>(entries); } @Override public synchronized Enumeration keys() // ensure it is sorted to be deterministic { final List keys = new LinkedList<>(); for (Object k : super.keySet()) { keys.add((String) k); } Collections.sort(keys); final Iterator it = keys.iterator(); return new Enumeration() { @Override public boolean hasMoreElements() { return it.hasNext(); } @Override public Object nextElement() { return it.next(); } }; } } ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/resource/properties/io/NoCloseOutputStream.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.resource.properties.io; import java.io.IOException; import java.io.OutputStream; /** * Simple output stream replacing close call by a simple flush. * Useful for output streams nesting streams (like jar output streams) and using a stream encoder. */ public class NoCloseOutputStream extends OutputStream { private final OutputStream delegate; public NoCloseOutputStream(OutputStream delegate) { this.delegate = delegate; } @Override public void write(int b) throws IOException { delegate.write(b); } @Override public void write(byte[] b) throws IOException { delegate.write(b); } @Override public void write(byte[] b, int off, int len) throws IOException { delegate.write(b, off, len); } @Override public void flush() throws IOException { delegate.flush(); } @Override public void close() throws IOException { delegate.flush(); } } ================================================ FILE: src/main/java/org/apache/maven/plugins/shade/resource/properties/io/SkipPropertiesDateLineWriter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.resource.properties.io; import java.io.BufferedWriter; import java.io.IOException; import java.io.Writer; /** * Simple buffered writer skipping its first write(String) call. */ public class SkipPropertiesDateLineWriter extends BufferedWriter { private State currentState = State.MUST_SKIP_DATE_COMMENT; public SkipPropertiesDateLineWriter(Writer out) { super(out); } @Override public void write(String str) throws IOException { if (currentState.shouldSkip(str)) { currentState = currentState.next(); return; } super.write(str); } private enum State { MUST_SKIP_DATE_COMMENT { @Override boolean shouldSkip(String content) { return content.length() > 1 && content.startsWith("#") && !content.startsWith("# "); } @Override State next() { return SKIPPED_DATE_COMMENT; } }, SKIPPED_DATE_COMMENT { @Override boolean shouldSkip(String content) { return content.trim().isEmpty(); } @Override State next() { return DONE; } }, DONE { @Override boolean shouldSkip(String content) { return false; } @Override State next() { throw new UnsupportedOperationException("done is a terminal state"); } }; abstract boolean shouldSkip(String content); abstract State next(); } } ================================================ FILE: src/site/apt/examples/attached-artifact.apt.vm ================================================ ------ Attaching the Shaded Artifact ------ Mauro Talevi ------ 2008-07-21 ------ ~~ 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. Attaching the Shaded Artifact By default, the plugin will replace the project's main artifact with the shaded artifact. If both the original and the shaded artifact should be installed/deployed to the repository, one can configure the plugin to attach the shaded artifact as a secondary artifact: +----- ... org.apache.maven.plugins maven-shade-plugin ${project.version} package shade true jackofall ... +----- The shaded artifact is distinguished from the main artifact by means of the additional classifier. ================================================ FILE: src/site/apt/examples/class-relocation.apt.vm ================================================ ------ Relocating Classes ------ Mauro Talevi ------ 2008-07-21 ------ ~~ 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. Relocating Classes If the uber JAR is reused as a dependency of some other project, directly including classes from the artifact's dependencies in the uber JAR can cause class loading conflicts due to duplicate classes on the class path. To address this issue, one can relocate the classes which get included in the shaded artifact in order to create a private copy of their bytecode: +----- ... org.apache.maven.plugins maven-shade-plugin ${project.version} package shade org.codehaus.plexus.util org.shaded.plexus.util org.codehaus.plexus.util.xml.Xpp3Dom org.codehaus.plexus.util.xml.pull.* ... +----- This instructs the plugin to move classes from the package <<>> and its subpackages into the package <<>> by moving the corresponding JAR file entries and rewriting the affected bytecode. The class <<>> and some others will remain in their original package. It's also possible to narrow the pattern with the <<>> and/or <<>> tag: +----- ... org.codehaus.plexus.util org.shaded.plexus.util org.codehaud.plexus.util.io.* org.codehaud.plexus.util.io.* ... +----- When using relocations with the <<>> element set to <<>>, both <<>> and <<>> are disregarded but the pattern is treated as {{{https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html}regular expression pattern}}. Also the <<>> and <<>> are always referring to a filesystem path (and must use forward slash (<<>>) as separator). Both are not normalized in this case. ================================================ FILE: src/site/apt/examples/executable-jar.apt.vm ================================================ ------ Executable JAR ------ Mauro Talevi ------ 2008-07-21 ------ ~~ 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. Executable JAR To create an executable uber JAR, one simply needs to set the main class that serves as the application entry point: +----- ... org.apache.maven.plugins maven-shade-plugin ${project.version} package shade org.sonatype.haven.HavenCli ... +----- This snippet configures a special resource transformer which sets the <<>> entry in the <<>> of the shaded JAR. Other entries can be added to the <<>> as well via key-value pairs in the <<<\>>> section: +----- ... org.apache.maven.plugins maven-shade-plugin ${project.version} package shade org.sonatype.haven.ExodusCli 123 ... +----- ================================================ FILE: src/site/apt/examples/includes-excludes.apt.vm ================================================ ------ Selecting Contents for Uber JAR ------ Mauro Talevi ------ 2008-07-21 ------ ~~ 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. Selecting Contents for Uber JAR The POM snippet below shows how to control which project dependencies should be included/excluded in the uber JAR: +----- ... org.apache.maven.plugins maven-shade-plugin ${project.version} package shade classworlds:classworlds junit:junit jmock:* *:xml-apis org.apache.maven:lib:tests log4j:log4j:jar: ... +----- Of course, <<<\>>> can be used as well to specify a white list of artifacts. Artifacts are denoted by a composite identifier of the form :[[:]:]. Since plugin version 1.3, the wildcard characters '*' and '?' can be used to do glob-like pattern matching. For fine-grained control of which classes from the selected dependencies are included, artifact filters can be used: +----- ... org.apache.maven.plugins maven-shade-plugin ${project.version} package shade junit:junit junit/framework/** org/junit/** org/junit/experimental/** org/junit/runners/** *:* META-INF/*.SF META-INF/*.DSA META-INF/*.RSA ... +----- Here, Ant-like patterns are used to specify that from the dependency <<>> only certain classes/resources should be included in the uber JAR. The second filter demonstrates the use of wildcards for the artifact identity which was introduced in plugin version 1.3. It excludes all signature related files from every artifact, regardless of its group or artifact id. Besides user-specified filters, the plugin can also be configured to automatically remove all classes of dependencies that are not used by the project, thereby minimizing the resulting uber JAR: +----- ... org.apache.maven.plugins maven-shade-plugin ${project.version} package shade true ... +----- As of version 1.6, minimizeJar will respect classes that were specifically marked for inclusion in a filter. Note that specifying an include filter for classes in an artifact implicitly excludes all non-specified classes in that artifact. <<<\false\<\\excludeDefaults\>>>> will override this behavior so that all non-specified classes still will be included though. +----- ... org.apache.maven.plugins maven-shade-plugin ${project.version} package shade true log4j:log4j ** commons-logging:commons-logging ** foo:bar false foo/Bar.class ... +----- ================================================ FILE: src/site/apt/examples/resource-transformers.apt.vm ================================================ ------ Resource Transformers ------ Mauro Talevi ------ 2008-07-21 ------ ~~ 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. Resource Transformers Aggregating classes/resources from several artifacts into one uber JAR is straight forward as long as there is no overlap. Otherwise, some kind of logic to merge resources from several JARs is required. This is where resource transformers kick in. *-----------------------------------------+------------------------------------------+ | {{ApacheLicenseResourceTransformer}} | Prevents license duplication | *-----------------------------------------+------------------------------------------+ | {{ApacheNoticeResourceTransformer}} | Prepares merged NOTICE | *-----------------------------------------+------------------------------------------+ | {{AppendingTransformer}} | Adds content to a resource | *-----------------------------------------+------------------------------------------+ | {{ComponentsXmlResourceTransformer}} | Aggregates Plexus <<>> | *-----------------------------------------+------------------------------------------+ | {{DontIncludeResourceTransformer}} | Prevents inclusion of matching resources | *-----------------------------------------+------------------------------------------+ | {{GroovyResourceTransformer}} | Merges Apache Groovy extends modules | *-----------------------------------------+------------------------------------------+ | {{IncludeResourceTransformer}} | Adds files from the project | *-----------------------------------------+------------------------------------------+ | {{ManifestResourceTransformer}} | Sets entries in the <<>> | *-----------------------------------------+------------------------------------------+ | {{PluginXmlResourceTransformer}} | Aggregates Mavens <<>> | *-----------------------------------------+------------------------------------------+ | {{ResourceBundleAppendingTransformer}} | Merges ResourceBundles | *-----------------------------------------+------------------------------------------+ | {{ServicesResourceTransformer}} | Relocated class names in <<>> resources and merges them. | *-----------------------------------------+------------------------------------------+ | {{XmlAppendingTransformer}} | Adds XML content to an XML resource | *-----------------------------------------+------------------------------------------+ Transformers in <<>> *-----------------------------------------+------------------------------------------+ | {{PropertiesTransformer}} | Merges properties files owning an ordinal to solve conflicts | *-----------------------------------------+------------------------------------------+ | {{OpenWebBeansPropertiesTransformer}} | Merges Apache OpenWebBeans configuration files | *-----------------------------------------+------------------------------------------+ | {{MicroprofileConfigTransformer}} | Merges conflicting Microprofile Config properties based on an ordinal | *-----------------------------------------+------------------------------------------+ Transformers in <<>> (available since 3.2.2) * Merging Plexus Component Descriptors with the {ComponentsXmlResourceTransformer} JARs for components targeting the Plexus IoC container contain a <<>> entry that declares the component and its requirements. If the uber JAR aggregates multiple Plexus components, a <<>> needs to be used to merge the XML descriptors: +----- ... org.apache.maven.plugins maven-shade-plugin ${project.version} shade ... +----- Since plugin version 1.3, this resource transformer will also update the descriptor to account for relocation of component interfaces/implementations (if any). * Relocate classes of the Maven Plugin Descriptor with the {PluginXmlResourceTransformer} With {{{http://maven.apache.org/plugin-tools/index.html}Plugin Tools 3.0}} annotations have been introduced. Now references to classes are no longer classnames as String, but the actual Class reference. When you wanted to relocate classes, you had to maintain the <<>> by hand, but now this can be done with the <<>> +----- ... org.apache.maven.plugins maven-shade-plugin ${project.version} shade ... +----- * Concatenating Service Entries with the {ServicesResourceTransformer} JAR files providing implementations of some interfaces often ship with a <<>> directory that maps interfaces to their implementation classes for lookup by the service locator. To relocate the class names of these implementation classes, and to merge multiple implementations of the same interface into one service entry, the <<>> can be used: +----- ... org.apache.maven.plugins maven-shade-plugin ${project.version} shade ... +----- * Merging Content of Specific Files with {AppendingTransformer}, XmlAppendingTransformer and ResourceBundleAppendingTransformer Some jars contain additional resources (such as properties files) that have the same file name. To avoid overwriting, you can opt to merge them by appending their content into one file. One good example for this is when aggregating both the spring-context and plexus-spring jars. Both of them have the <<>> file which is used by Spring to handle XML schema namespaces. You can merge the contents of all the files with that specific name using the <<>> as shown below: +----- ... org.apache.maven.plugins maven-shade-plugin ${project.version} shade META-INF/spring.handlers META-INF/spring.schemas ... +----- For XML files, you can use the <<<{XmlAppendingTransformer}>>> instead: +----- ... org.apache.maven.plugins maven-shade-plugin ${project.version} shade META-INF/magic.xml ... +----- Since plugin version 1.3.1, the <<>> will by default not load DTDs, thereby avoiding network access. The potential downside of this mode is that external entities cannot be resolved which could fail the transformation, e.g. when using the Crimson XML parser as used in some JRE 1.4. If the transformed resource uses external entities, DTD resolution can either be turned back on or a plugin dependency on <<>> is added to the POM. For ResourceBundles properties files, you can use the <<<{ResourceBundleAppendingTransformer}>>> instead, which will respect all available Locales as well: +----- ... org.apache.maven.plugins maven-shade-plugin ${project.version} shade path/to/Messages ... +----- * Excluding Resources with the {DontIncludeResourceTransformer} The <<>> allows resources to be excluded when their name ends in a given value. For example, the following sample excludes all resources ending in <<<.txt>>>. +----- ... org.apache.maven.plugins maven-shade-plugin ${project.version} shade .txt ... +----- Since maven-shade-plugin-3.0 it is also possible to give a list of resources which should not be included, like: +----- .txt READ.me +----- * Adding New Resources with the {IncludeResourceTransformer} The <<>> allows project files to be included in the package under a given name. For example, the following sample includes <<>> in the package as <<>> in the <<>> directory. +----- ... org.apache.maven.plugins maven-shade-plugin ${project.version} shade META-INF/README README.txt ... +----- * Setting Manifest Entries with the {ManifestResourceTransformer} The <<>> allows existing entries in the <<>> to be replaced and new entries added. For example, the following sample sets * the <<>> entry to the value of the <<>> property, * the <<>> entry to the value of the <<>> property and * the <<>> entry to the value of the <<>> property. By default the <<>> will relocate the following attributes: * Export-Package * Import-Package * Provide-Capability * Require-Capability With <<>> you can specify the attributes that need to be relocated too. +----- ... org.apache.maven.plugins maven-shade-plugin ${project.version} shade ${app.main.class} ${maven.compile.source} ${maven.compile.target} ... +----- * Licensing ** Preventing License Duplication with the {ApacheLicenseResourceTransformer} Some open source producers (including the {{{https://www.apache.org} Apache Software Foundation}}) include a copy of their license in the META-INF directory. These are conventionally named either <<>>,<<>> or <<>>. When merging these dependencies, adding these resources may cause confusion. The <<>> ensures that duplicate licenses (named according to this convention) are not merged. For example, the following prevents the license from a <<>> dependency being merged in +----- ... org.apache.maven.plugins maven-shade-plugin ${project.version} shade ... +----- ** Aggregating Notices with the {ApacheNoticeResourceTransformer} Some licenses (including the {{{https://www.apache.org/licenses/LICENSE-2.0.html} Apache License, Version 2}}) require that notices are preserved by downstream distributors. <<>> automates the assembly of an appropriate <<>>. For example, to simply merge in dependent notices: +----- ... org.apache.maven.plugins maven-shade-plugin ${project.version} shade false ... +----- ** Aggregating Apache Groovy extension modules descriptors with the {GroovyResourceTransformer} The Apache Groovy language provides extension modules located at <<>>, these modules use the property file format. <<>> automates the assembly of Groovy extension modules <<>>. For example, to simply merge the extension modules of several jars: +----- ... org.apache.maven.plugins maven-shade-plugin ${project.version} shade the-aggregated-module 1.0.0 ... +----- * Merging properties files with {PropertiesTransformer} The <<>> allows a set of properties files to be merged and to resolve conflicts based on an ordinal giving the priority of each file. An optional <<>> enables to have a boolean flag in the file which, if set to true, request to use the file as it as the result of the merge. If two files are considered complete in the merge process then the shade will fail. +----- ... org.apache.maven.plugins maven-shade-plugin ${project.version} shade configuration/application.properties ordinal already_merged 0 false ... +----- * Merging Apache OpenWebBeans configuration with {OpenWebBeansPropertiesTransformer} <<>> preconfigure a <<>> for Apache OpenWebBeans configuration files. +----- ... org.apache.maven.plugins maven-shade-plugin ${project.version} shade ... +----- * Merging Microprofile Config properties with {MicroprofileConfigTransformer} <<>> preconfigure a <<>> for Microprofile Config. The only required configuration is the ordinal. The <<>> is supported but is not defined by the specification. +----- ... org.apache.maven.plugins maven-shade-plugin ${project.version} shade configuration/app.properties ... +----- ================================================ FILE: src/site/apt/examples/use-shader-other-impl.apt.vm ================================================ ------ Using an other Shader Implementation ------ Olivier Lamy ------ 2012-03-13 ------ ~~ 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. Using your own Shader implementation By default, the plugin provide a DefaultShader implementation but with version 1.6 you can use your own implementation. Create a standard Maven project with your implementation. +----- Dependency to Plexus annotations org.codehaus.plexus plexus-component-annotations 1.5.5 Create your Shader @Component( role = Shader.class, hint = "mock" ) public class MockShader implements Shader { // implement the interface here } // Use the plexus component metadata plugin in your job to generate Plexus metadata org.codehaus.plexus plexus-component-metadata 1.5.5 generate-metadata +----- Assuming your project has coordinate org.foo.bar:wine:1.0, you must add it as a dependency of the shade plugin. +----- ... org.apache.maven.plugins maven-shade-plugin ${project.version} org.foo.bar wine 1.0 package shade mock ... +----- Now the mojo will use your own implementation. ================================================ FILE: src/site/apt/index.apt.vm ================================================ ------ Introduction ------ Mauro Talevi ------ 2013-07-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. ${project.name} This plugin provides the capability to package the artifact in an uber-jar, including its dependencies and to - i.e. rename - the packages of some of the dependencies. * Goals Overview The Shade Plugin has a single goal: * {{{./shade-mojo.html}shade:shade}} is bound to the <<>> phase and is used to create a shaded jar. * Usage General instructions on how to use the Shade Plugin can be found on the {{{./usage.html}usage page}}. Some more specific use cases are described in the examples given below. In case you still have questions regarding the plugin's usage, please feel free to contact the {{{./mailing-lists.html}user mailing list}}. The posts to the mailing list are archived and could already contain the answer to your question as part of an older thread. Hence, it is also worth browsing/searching the {{{./mail-lists.html}mail archive}}. If you feel like the plugin is missing a feature or has a defect, you can fill a feature request or bug report in our {{{./issue-management.html}issue tracker}}. When creating a new issue, please provide a comprehensive description of your concern. Especially for fixing bugs it is crucial that the developers can reproduce your problem. For this reason, entire debug logs, POMs or most preferably little demo projects attached to the issue are very much appreciated. Of course, patches are welcome, too. Contributors can check out the project from our {{{./scm.html}source repository}} and will find supplementary information in the {{{http://maven.apache.org/guides/development/guide-helping.html}guide to helping with Maven}}. * Examples To provide you with better understanding on some usages of the Shade Plugin, you can take a look into the following examples: * {{{./examples/includes-excludes.html}Selecting Contents for Uber JAR}} * {{{./examples/class-relocation.html}Relocating Classes}} * {{{./examples/attached-artifact.html}Attaching the Shaded Artifact}} * {{{./examples/executable-jar.html}Executable JAR}} * {{{./examples/resource-transformers.html}Resource Transformers}} * {{{./examples/use-shader-other-impl.html}Using another Shader implementation}} [] ================================================ FILE: src/site/apt/usage.apt.vm ================================================ ------ Usage ------ Mauro Talevi ------ 2008-07-21 ------ ~~ 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. Usage * Creating a Shaded JAR The goals for the Shade Plugin are bound to the <<>> phase in the build lifecycle. +----- mvn package +----- * Configuring Your Shade Plugin +----- ... org.apache.maven.plugins maven-shade-plugin ${currentVersion} package shade ... +----- * Resource Transformers *-----------------------------------------+--------------------------------------+ | ApacheLicenseResourceTransformer | Prevents license duplication | *-----------------------------------------+--------------------------------------+ | ApacheNoticeResourceTransformer | Prepares merged NOTICE | *-----------------------------------------+--------------------------------------+ | AppendingTransformer | Adds content to a resource | *-----------------------------------------+--------------------------------------+ | ComponentsXmlResourceTransformer | Aggregates Plexus <<>>| *-----------------------------------------+--------------------------------------+ | DontIncludeResourceTransformer | Prevents inclusion of matching resources | *-----------------------------------------+--------------------------------------+ | IncludeResourceTransformer | Adds files from the project | *-----------------------------------------+--------------------------------------+ | ManifestResourceTransformer | Sets entries in the <<>> | *-----------------------------------------+--------------------------------------+ | ServicesResourceTransformer | Merges <<>> resources | *-----------------------------------------+--------------------------------------+ | XmlAppendingTransformer | Adds XML content to an XML resource | *-----------------------------------------+--------------------------------------+ Transformers in <<>> For more information, see {{{./examples/resource-transformers.html}samples}}. ================================================ FILE: src/site/fml/faq.fml ================================================ Why Does My Second Shade Include The Results Of The First Execution?

By default, shade replaces with original jar with the result of shading. So, when a pom.xml includes two shades, the second shade execution will (by default) start from the result of the first shade execution.

If you're looking for two independent shades then read in shade:shade about ways choose a different name for your first shade.

================================================ FILE: src/site/resources/download.cgi ================================================ #!/bin/sh # # 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. # # Just call the standard mirrors.cgi script. It will use download.html # as the input template. exec /www/www.apache.org/dyn/mirrors/mirrors.cgi $* ================================================ FILE: src/site/site.xml ================================================ ================================================ FILE: src/site/xdoc/download.xml.vm ================================================ Download ${project.name} Source

${project.name} ${project.version} is distributed in source format.

Use a source archive if you intend to build ${project.name} yourself.

Otherwise, simply use the ready-made binary artifacts from central repository.

${project.name} is distributed under the Apache License, version 2.0.

This is the current stable version of ${project.name}.

Link Checksum Signature
${project.name} ${project.version} (Source zip) ${project.artifactId}-${project.version}-source-release.zip ${project.artifactId}-${project.version}-source-release.zip.sha512 ${project.artifactId}-${project.version}-source-release.zip.asc

It is essential that you verify the integrity of the downloaded file using the checksum (.sha512 file) or using the signature (.asc file) against the public KEYS used by the Apache Maven developers.

It is strongly recommended to use the latest release version of ${project.name} to take advantage of the newest features and bug fixes.

Older non-recommended releases can be found on our archive site.

================================================ FILE: src/test/java/org/apache/maven/plugins/shade/DefaultShaderTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.lang.reflect.Field; import java.net.URL; import java.net.URLClassLoader; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.nio.file.attribute.FileTime; 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; import java.util.zip.ZipEntry; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugins.shade.filter.Filter; import org.apache.maven.plugins.shade.relocation.Relocator; import org.apache.maven.plugins.shade.relocation.SimpleRelocator; import org.apache.maven.plugins.shade.resource.AppendingTransformer; import org.apache.maven.plugins.shade.resource.ComponentsXmlResourceTransformer; import org.apache.maven.plugins.shade.resource.ResourceTransformer; 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; import org.objectweb.asm.ClassReader; 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 java.util.Objects.requireNonNull; import static org.codehaus.plexus.util.FileUtils.forceMkdir; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.hasItem; import static org.hamcrest.CoreMatchers.hasItems; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; /** * @author Jason van Zyl * @author Mauro Talevi */ 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 TEMPORARY_FOLDER = new TemporaryFolder(); private static final String NEWLINE = "\n"; @Test public void testNoopWhenNotRelocated() throws IOException, MojoExecutionException { File plexusJar = new File("src/test/jars/plexus-utils-1.4.1.jar"); File shadedOutput = new File("target/foo-custom_testNoopWhenNotRelocated.jar"); Set jars = new LinkedHashSet<>(); jars.add(new File("src/test/jars/test-project-1.0-SNAPSHOT.jar")); jars.add(plexusJar); Relocator relocator = new SimpleRelocator( "org/codehaus/plexus/util/cli", "relocated/plexus/util/cli", Collections.emptyList(), Collections.emptyList()); ShadeRequest shadeRequest = new ShadeRequest(); shadeRequest.setJars(jars); shadeRequest.setRelocators(Collections.singletonList(relocator)); shadeRequest.setResourceTransformers(Collections.emptyList()); shadeRequest.setFilters(Collections.emptyList()); shadeRequest.setUberJar(shadedOutput); DefaultShader shader = newShader(); shader.shade(shadeRequest); try (JarFile originalJar = new JarFile(plexusJar); JarFile shadedJar = new JarFile(shadedOutput)) { // ASM processes all class files. In doing so, it modifies them, even when not relocating anything. // 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. assertTrue(areEqual(originalJar, shadedJar, "org/codehaus/plexus/util/Expand.class")); // Relocated files should always be different, because they contain different package names in their byte // code. We should verify this anyway, in order to avoid an existing class file from simply being moved to // another location without actually having been relocated internally. assertFalse(areEqual( originalJar, shadedJar, "org/codehaus/plexus/util/cli/Arg.class", "relocated/plexus/util/cli/Arg.class")); } int result = 0; for (String msg : debugMessages.getAllValues()) { if ("Rewrote class bytecode: org/codehaus/plexus/util/cli/Arg.class".equals(msg)) { result |= 1; } else if ("Keeping original class bytecode: org/codehaus/plexus/util/Expand.class".equals(msg)) { result |= 2; } } assertEquals(3 /* 1 | 2 */, result); } @Test public void testOverlappingResourcesAreLogged() throws IOException, MojoExecutionException { DefaultShader shader = newShader(); // we will shade two jars and expect to see META-INF/MANIFEST.MF overlaps, this will always be true // but this can lead to a broken deployment if intended for OSGi or so, so even this should be logged Set 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")); ShadeRequest shadeRequest = new ShadeRequest(); shadeRequest.setJars(set); shadeRequest.setRelocators(Collections.emptyList()); shadeRequest.setResourceTransformers(Collections.emptyList()); shadeRequest.setFilters(Collections.emptyList()); shadeRequest.setUberJar(new File("target/foo-custom_testOverlappingResourcesAreLogged.jar")); shader.shade(shadeRequest); assertThat( warnMessages.getAllValues(), hasItem(containsString( "plexus-utils-1.4.1.jar, test-project-1.0-SNAPSHOT.jar define 1 overlapping resource:"))); assertThat(warnMessages.getAllValues(), hasItem(containsString("- META-INF/MANIFEST.MF"))); if (Os.isFamily(Os.FAMILY_WINDOWS)) { assertThat( debugMessages.getAllValues(), hasItem(containsString( "We have a duplicate META-INF/MANIFEST.MF in src\\test\\jars\\plexus-utils-1.4.1.jar"))); } else { assertThat( debugMessages.getAllValues(), hasItem(containsString( "We have a duplicate META-INF/MANIFEST.MF in src/test/jars/plexus-utils-1.4.1.jar"))); } } @Test public void testOverlappingResourcesAreLoggedExceptATransformerHandlesIt() throws Exception { TemporaryFolder temporaryFolder = new TemporaryFolder(); try { Set set = new LinkedHashSet<>(); temporaryFolder.create(); File j1 = temporaryFolder.newFile("j1.jar"); try (JarOutputStream jos = new JarOutputStream(new FileOutputStream(j1))) { jos.putNextEntry(new JarEntry("foo.txt")); jos.write("c1".getBytes(StandardCharsets.UTF_8)); jos.closeEntry(); } File j2 = temporaryFolder.newFile("j2.jar"); try (JarOutputStream jos = new JarOutputStream(new FileOutputStream(j2))) { jos.putNextEntry(new JarEntry("foo.txt")); jos.write("c2".getBytes(StandardCharsets.UTF_8)); jos.closeEntry(); } set.add(j1); set.add(j2); AppendingTransformer transformer = new AppendingTransformer(); Field resource = AppendingTransformer.class.getDeclaredField("resource"); resource.setAccessible(true); resource.set(transformer, "foo.txt"); ShadeRequest shadeRequest = new ShadeRequest(); shadeRequest.setJars(set); shadeRequest.setRelocators(Collections.emptyList()); shadeRequest.setResourceTransformers(Collections.singletonList(transformer)); shadeRequest.setFilters(Collections.emptyList()); shadeRequest.setUberJar(new File("target/foo-custom_testOverlappingResourcesAreLogged.jar")); DefaultShader shaderWithTransformer = newShader(); shaderWithTransformer.shade(shadeRequest); assertThat(warnMessages.getAllValues().size(), is(0)); DefaultShader shaderWithoutTransformer = newShader(); shadeRequest.setResourceTransformers(Collections.emptyList()); shaderWithoutTransformer.shade(shadeRequest); assertThat( warnMessages.getAllValues(), hasItems(containsString("j1.jar, j2.jar define 1 overlapping resource:"))); assertThat(warnMessages.getAllValues(), hasItems(containsString("- foo.txt"))); } finally { temporaryFolder.delete(); } } @Test public void testShaderWithDefaultShadedPattern() throws Exception { shaderWithPattern(null, new File("target/foo-default.jar"), EXCLUDES); } @Test public void testShaderWithStaticInitializedClass() throws Exception { Shader s = newShader(); Set set = new LinkedHashSet<>(); set.add(new File("src/test/jars/test-artifact-1.0-SNAPSHOT.jar")); List relocators = new ArrayList<>(); relocators.add(new SimpleRelocator("org.apache.maven.plugins.shade", null, null, null)); List resourceTransformers = new ArrayList<>(); List filters = new ArrayList<>(); File file = new File("target/testShaderWithStaticInitializedClass.jar"); ShadeRequest shadeRequest = new ShadeRequest(); shadeRequest.setJars(set); shadeRequest.setUberJar(file); shadeRequest.setFilters(filters); shadeRequest.setRelocators(relocators); shadeRequest.setResourceTransformers(resourceTransformers); s.shade(shadeRequest); try (URLClassLoader cl = new URLClassLoader(new URL[] {file.toURI().toURL()})) { Class c = cl.loadClass("hidden.org.apache.maven.plugins.shade.Lib"); Object o = c.newInstance(); assertEquals("foo.bar/baz", c.getDeclaredField("CONSTANT").get(o)); } } @Test public void testShaderWithCustomShadedPattern() throws Exception { shaderWithPattern("org/shaded/plexus/util", new File("target/foo-custom.jar"), EXCLUDES); } @Test public void testShaderWithoutExcludesShouldRemoveReferencesOfOriginalPattern() throws Exception { // FIXME: shaded jar should not include references to org/codehaus/* (empty dirs) or org.codehaus.* META-INF // files. shaderWithPattern( "org/shaded/plexus/util", new File("target/foo-custom-without-excludes.jar"), new String[] {}); } @Test public void testHandleDirectory() throws Exception { final File dir = TEMPORARY_FOLDER.getRoot(); // explode src/test/jars/test-artifact-1.0-SNAPSHOT.jar in this temp dir try (JarInputStream in = new JarInputStream(Files.newInputStream(Paths.get("src/test/jars/test-artifact-1.0-SNAPSHOT.jar")))) { JarEntry nextJarEntry; while ((nextJarEntry = in.getNextJarEntry()) != null) { if (nextJarEntry.isDirectory()) { continue; } File out = new File(dir, nextJarEntry.getName()); forceMkdir(out.getParentFile()); try (OutputStream outputStream = Files.newOutputStream(out.toPath())) { IOUtil.copy(in, outputStream, (int) Math.max(nextJarEntry.getSize(), 512)); } } } // do shade File shade = new File("target/testHandleDirectory.jar"); shaderWithPattern("org/shaded/plexus/util", shade, new String[0], singleton(dir)); // ensure directory was shaded properly try (JarFile jar = new JarFile(shade)) { List entries = new ArrayList<>(); Enumeration jarEntryEnumeration = jar.entries(); while (jarEntryEnumeration.hasMoreElements()) { 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 { DefaultShader s = newShader(); Set 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")); List relocators = new ArrayList<>(); relocators.add( new SimpleRelocator("org/codehaus/plexus/util/", "_plexus/util/__", null, Collections.emptyList())); List resourceTransformers = new ArrayList<>(); resourceTransformers.add(new ComponentsXmlResourceTransformer()); List filters = new ArrayList<>(); File file = new File("target/foo-relocate-class.jar"); ShadeRequest shadeRequest = new ShadeRequest(); shadeRequest.setJars(set); shadeRequest.setUberJar(file); shadeRequest.setFilters(filters); shadeRequest.setRelocators(relocators); shadeRequest.setResourceTransformers(resourceTransformers); s.shade(shadeRequest); try (URLClassLoader cl = new URLClassLoader(new URL[] {file.toURI().toURL()})) { Class c = cl.loadClass("_plexus.util.__StringUtils"); // first, ensure it works: Object o = c.newInstance(); assertEquals("", c.getMethod("clean", String.class).invoke(o, (String) null)); // now, check that its source file was rewritten: String[] source = {null}; ClassReader classReader = new ClassReader(cl.getResourceAsStream("_plexus/util/__StringUtils.class")); classReader.accept( new ClassVisitor(Opcodes.ASM4) { @Override public void visitSource(String arg0, String arg1) { super.visitSource(arg0, arg1); source[0] = arg0; } }, ClassReader.SKIP_CODE); assertEquals("__StringUtils.java", source[0]); } } @Test public void testShaderWithNestedJar() throws Exception { TemporaryFolder temporaryFolder = new TemporaryFolder(); final String innerJarFileName = "inner.jar"; temporaryFolder.create(); File innerJar = temporaryFolder.newFile(innerJarFileName); try (JarOutputStream jos = new JarOutputStream(Files.newOutputStream(innerJar.toPath()))) { jos.putNextEntry(new JarEntry("foo.txt")); jos.write("c1".getBytes(StandardCharsets.UTF_8)); jos.closeEntry(); } ShadeRequest shadeRequest = new ShadeRequest(); shadeRequest.setJars(new LinkedHashSet<>(Collections.singleton(innerJar))); shadeRequest.setFilters(Collections.emptyList()); shadeRequest.setRelocators(Collections.emptyList()); shadeRequest.setResourceTransformers(Collections.emptyList()); File shadedFile = temporaryFolder.newFile("shaded.jar"); shadeRequest.setUberJar(shadedFile); DefaultShader shader = newShader(); shader.shade(shadeRequest); FileTime lastModified = FileTime.from( Files.getLastModifiedTime(shadedFile.toPath()).toInstant().minus(5, ChronoUnit.SECONDS)); Files.setLastModifiedTime(shadedFile.toPath(), lastModified); shader.shade(shadeRequest); assertEquals(lastModified, Files.getLastModifiedTime(shadedFile.toPath())); temporaryFolder.delete(); } @Test public void testShaderNoOverwrite() throws Exception { TemporaryFolder temporaryFolder = new TemporaryFolder(); final String innerJarFileName = "inner.jar"; temporaryFolder.create(); File innerJar = temporaryFolder.newFile(innerJarFileName); try (JarOutputStream jos = new JarOutputStream(new FileOutputStream(innerJar))) { jos.putNextEntry(new JarEntry("foo.txt")); jos.write("c1".getBytes(StandardCharsets.UTF_8)); jos.closeEntry(); } File outerJar = temporaryFolder.newFile("outer.jar"); try (JarOutputStream jos = new JarOutputStream(new FileOutputStream(outerJar))) { FileInputStream innerStream = new FileInputStream(innerJar); byte[] bytes = IOUtil.toByteArray(innerStream, 32 * 1024); innerStream.close(); writeEntryWithoutCompression(innerJarFileName, bytes, jos); } ShadeRequest shadeRequest = new ShadeRequest(); shadeRequest.setJars(new LinkedHashSet<>(Collections.singleton(outerJar))); shadeRequest.setFilters(new ArrayList<>()); shadeRequest.setRelocators(new ArrayList<>()); shadeRequest.setResourceTransformers(new ArrayList<>()); File shadedFile = temporaryFolder.newFile("shaded.jar"); shadeRequest.setUberJar(shadedFile); DefaultShader shader = newShader(); shader.shade(shadeRequest); JarFile shadedJarFile = new JarFile(shadedFile); JarEntry entry = shadedJarFile.getJarEntry(innerJarFileName); // After shading, entry compression method should not be changed. Assert.assertEquals(entry.getMethod(), ZipEntry.STORED); temporaryFolder.delete(); } @Test public void testShaderWithDuplicateService() throws Exception { TemporaryFolder temporaryFolder = new TemporaryFolder(); temporaryFolder.create(); String serviceEntryName = "META-INF/services/my.foo.Service"; String serviceEntryValue = "my.foo.impl.Service1"; File innerJar1 = temporaryFolder.newFile("inner1.jar"); try (JarOutputStream jos = new JarOutputStream(Files.newOutputStream(innerJar1.toPath()))) { jos.putNextEntry(new JarEntry(serviceEntryName)); jos.write((serviceEntryValue + NEWLINE).getBytes(StandardCharsets.UTF_8)); jos.closeEntry(); } File innerJar2 = temporaryFolder.newFile("inner2.jar"); try (JarOutputStream jos = new JarOutputStream(Files.newOutputStream(innerJar2.toPath()))) { jos.putNextEntry(new JarEntry(serviceEntryName)); jos.write((serviceEntryValue + NEWLINE).getBytes(StandardCharsets.UTF_8)); jos.closeEntry(); } ShadeRequest shadeRequest = new ShadeRequest(); shadeRequest.setJars(new LinkedHashSet<>(Arrays.asList(innerJar1, innerJar2))); shadeRequest.setFilters(Collections.emptyList()); shadeRequest.setRelocators(Collections.emptyList()); shadeRequest.setResourceTransformers(Collections.singletonList(new ServicesResourceTransformer())); File shadedFile = temporaryFolder.newFile("shaded.jar"); shadeRequest.setUberJar(shadedFile); DefaultShader shader = newShader(); shader.shade(shadeRequest); JarFile shadedJarFile = new JarFile(shadedFile); JarEntry entry = shadedJarFile.getJarEntry(serviceEntryName); List lines = new BufferedReader( new InputStreamReader(shadedJarFile.getInputStream(entry), StandardCharsets.UTF_8)) .lines() .collect(Collectors.toList()); // After shading, there should be a single input Assert.assertEquals(Collections.singletonList(serviceEntryValue), lines); temporaryFolder.delete(); } @Test public void testShaderWithSmallEntries() throws Exception { TemporaryFolder temporaryFolder = new TemporaryFolder(); final String innerJarFileName = "inner.jar"; int len; temporaryFolder.create(); File innerJar = temporaryFolder.newFile(innerJarFileName); try (JarOutputStream jos = new JarOutputStream(Files.newOutputStream(innerJar.toPath()))) { jos.putNextEntry(new JarEntry("foo.txt")); byte[] bytes = "c1".getBytes(StandardCharsets.UTF_8); len = bytes.length; jos.write(bytes); jos.closeEntry(); } ShadeRequest shadeRequest = new ShadeRequest(); shadeRequest.setJars(new LinkedHashSet<>(Collections.singleton(innerJar))); shadeRequest.setFilters(new ArrayList<>()); shadeRequest.setRelocators(new ArrayList<>()); shadeRequest.setResourceTransformers(new ArrayList<>()); File shadedFile = temporaryFolder.newFile("shaded.jar"); shadeRequest.setUberJar(shadedFile); DefaultShader shader = newShader(); shader.shade(shadeRequest); JarFile shadedJarFile = new JarFile(shadedFile); JarEntry entry = shadedJarFile.getJarEntry("foo.txt"); // After shading, entry compression method should not be changed. Assert.assertEquals(entry.getSize(), len); temporaryFolder.delete(); } private void writeEntryWithoutCompression(String entryName, byte[] entryBytes, JarOutputStream jos) throws IOException { final JarEntry entry = new JarEntry(entryName); final int size = entryBytes.length; final CRC32 crc = new CRC32(); crc.update(entryBytes, 0, size); entry.setSize(size); entry.setCompressedSize(size); entry.setMethod(ZipEntry.STORED); entry.setCrc(crc.getValue()); jos.putNextEntry(entry); jos.write(entryBytes); jos.closeEntry(); } private void shaderWithPattern(String shadedPattern, File jar, String[] excludes) throws Exception { Set 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 set) throws Exception { DefaultShader s = newShader(); List relocators = new ArrayList<>(); relocators.add(new SimpleRelocator("org/codehaus/plexus/util", shadedPattern, null, Arrays.asList(excludes))); List resourceTransformers = new ArrayList<>(); resourceTransformers.add(new ComponentsXmlResourceTransformer()); List filters = new ArrayList<>(); ShadeRequest shadeRequest = new ShadeRequest(); shadeRequest.setJars(set); shadeRequest.setUberJar(jar); shadeRequest.setFilters(filters); shadeRequest.setRelocators(relocators); shadeRequest.setResourceTransformers(resourceTransformers); s.shade(shadeRequest); } private DefaultShader newShader() { return new DefaultShader(mockLogger()); } private ArgumentCaptor debugMessages; private ArgumentCaptor warnMessages; private Logger mockLogger() { debugMessages = ArgumentCaptor.forClass(String.class); warnMessages = ArgumentCaptor.forClass(String.class); Logger logger = mock(Logger.class); when(logger.isDebugEnabled()).thenReturn(true); when(logger.isWarnEnabled()).thenReturn(true); doNothing().when(logger).debug(debugMessages.capture()); doNothing().when(logger).warn(warnMessages.capture()); return logger; } private boolean areEqual(final JarFile jar1, final JarFile jar2, final String entry) throws IOException { return areEqual(jar1, jar2, entry, entry); } private boolean areEqual(final JarFile jar1, final JarFile jar2, final String entry1, String entry2) throws IOException { try (InputStream s1 = jar1.getInputStream( requireNonNull(jar1.getJarEntry(entry1), entry1 + " in " + jar1.getName())); InputStream s2 = jar2.getInputStream( requireNonNull(jar2.getJarEntry(entry2), entry2 + " in " + jar2.getName()))) { return Arrays.equals(IOUtil.toByteArray(s1), IOUtil.toByteArray(s2)); } } } ================================================ FILE: src/test/java/org/apache/maven/plugins/shade/MockShader.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade; import javax.inject.Named; import javax.inject.Singleton; import java.io.IOException; import org.apache.maven.plugin.MojoExecutionException; /** * @author Olivier Lamy */ @Singleton @Named("mock") public class MockShader implements Shader { public void shade(ShadeRequest shadeRequest) throws IOException, MojoExecutionException { System.out.println("Executing MockShader#shade"); } } ================================================ FILE: src/test/java/org/apache/maven/plugins/shade/custom/CustomReproducibleResourceTransformer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.custom; import java.io.IOException; import java.io.InputStream; import java.util.List; import java.util.jar.JarOutputStream; import org.apache.maven.plugins.shade.relocation.Relocator; import org.apache.maven.plugins.shade.resource.ReproducibleResourceTransformer; /** * Custom ReproducibleResourceTransformer for MSHADE-363_old-plugin IT, to check that it can be run with * an older maven-shade-plugin that does not contain the ReproducibleResourceTransformer interface. */ public class CustomReproducibleResourceTransformer implements ReproducibleResourceTransformer { @Override public boolean canTransformResource(final String resource) { return true; } /** * old non-reproducible RessourceTransformer API that will be used by maven-shade-plugin up to 3.2.2. */ @Override public final void processResource(final String resource, final InputStream is, final List relocators) throws IOException { System.out.println("Custom ResourceTransformer called through old API"); // call new ReproducibleRessourceTransformer API using a conventional timestamp processResource(resource, is, relocators, 0); } /** * new reproducible API */ @Override public void processResource( final String resource, final InputStream is, final List relocators, long time) throws IOException { System.out.println("Custom ResourceTransformer called through new Reprodcible API"); } @Override public boolean hasTransformedResource() { return true; } @Override public void modifyOutputStream(JarOutputStream os) throws IOException { // do-op for this test } } ================================================ FILE: src/test/java/org/apache/maven/plugins/shade/filter/MinijarFilterTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.filter; import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Set; import java.util.TreeSet; import java.util.jar.JarOutputStream; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.DefaultArtifact; import org.apache.maven.artifact.DependencyResolutionRequiredException; import org.apache.maven.model.Build; import org.apache.maven.plugin.logging.Log; import org.apache.maven.project.MavenProject; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.mockito.ArgumentCaptor; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import static org.junit.Assume.assumeFalse; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; public class MinijarFilterTest { @Rule public TemporaryFolder tempFolder = TemporaryFolder.builder().assureDeletion().build(); private File outputDirectory; private File emptyFile; private File jarFile; private Log log; private ArgumentCaptor logCaptor; @Before public void init() throws IOException { this.outputDirectory = tempFolder.newFolder(); this.emptyFile = tempFolder.newFile(); this.jarFile = tempFolder.newFile(); new JarOutputStream(Files.newOutputStream(this.jarFile.toPath())).close(); this.log = mock(Log.class); logCaptor = ArgumentCaptor.forClass(CharSequence.class); } /** * This test will fail on JDK 7 because jdependency needs at least JDK 8. */ @Test public void testWithMockProject() throws IOException { assumeFalse( "Expected to run under JDK8+", System.getProperty("java.version").startsWith("1.7")); MavenProject mavenProject = mockProject(outputDirectory, emptyFile); MinijarFilter mf = new MinijarFilter(mavenProject, log); mf.finished(); verify(log).info(logCaptor.capture()); assertEquals("Minimized 0 -> 0", logCaptor.getValue()); } @Test public void testWithPomProject() throws IOException { // project with pom packaging and no artifact. MavenProject mavenProject = mockProject(outputDirectory, null); mavenProject.setPackaging("pom"); MinijarFilter mf = new MinijarFilter(mavenProject, log); mf.finished(); verify(log).info(logCaptor.capture()); // verify no access to project's artifacts verify(mavenProject, never()).getArtifacts(); assertEquals("Minimized 0 -> 0", logCaptor.getValue()); } private MavenProject mockProject(File outputDirectory, File file, String... classPathElements) { MavenProject mavenProject = mock(MavenProject.class); Artifact artifact = mock(Artifact.class); when(artifact.getGroupId()).thenReturn("com"); when(artifact.getArtifactId()).thenReturn("aid"); when(artifact.getVersion()).thenReturn("1.9"); when(artifact.getClassifier()).thenReturn("classifier1"); when(artifact.getScope()).thenReturn(Artifact.SCOPE_COMPILE); when(mavenProject.getArtifact()).thenReturn(artifact); DefaultArtifact dependencyArtifact = new DefaultArtifact("dep.com", "dep.aid", "1.0", "compile", "jar", "classifier2", null); dependencyArtifact.setFile(file); Set artifacts = new TreeSet<>(); artifacts.add(dependencyArtifact); when(mavenProject.getArtifacts()).thenReturn(artifacts); when(mavenProject.getArtifact().getFile()).thenReturn(file); Build build = new Build(); build.setOutputDirectory(outputDirectory.toString()); List classpath = new ArrayList<>(); classpath.add(outputDirectory.toString()); if (file != null) { classpath.add(file.toString()); } classpath.addAll(Arrays.asList(classPathElements)); when(mavenProject.getBuild()).thenReturn(build); try { when(mavenProject.getRuntimeClasspathElements()).thenReturn(classpath); } catch (DependencyResolutionRequiredException e) { fail("Encountered unexpected exception: " + e.getClass().getSimpleName() + ": " + e.getMessage()); } return mavenProject; } @Test public void finsishedShouldProduceMessageForClassesTotalNonZero() { MinijarFilter m = new MinijarFilter(1, 50, log); m.finished(); verify(log).info(logCaptor.capture()); assertEquals("Minimized 51 -> 1 (1%)", logCaptor.getValue()); } @Test public void finishedShouldProduceMessageForClassesTotalZero() { MinijarFilter m = new MinijarFilter(0, 0, log); m.finished(); verify(log).info(logCaptor.capture()); assertEquals("Minimized 0 -> 0", logCaptor.getValue()); } } ================================================ FILE: src/test/java/org/apache/maven/plugins/shade/filter/SimpleFilterTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.filter; import java.util.Collections; import org.apache.maven.plugins.shade.mojo.ArchiveFilter; import org.junit.Test; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; /** * @author Benjamin Bentmann */ public class SimpleFilterTest { @Test public void testIsFiltered() { SimpleFilter filter; filter = new SimpleFilter(null, null, null); assertFalse(filter.isFiltered("a.properties")); assertFalse(filter.isFiltered("org/Test.class")); filter = new SimpleFilter(null, Collections.emptySet(), Collections.emptySet()); assertFalse(filter.isFiltered("a.properties")); assertFalse(filter.isFiltered("org/Test.class")); filter = new SimpleFilter(null, Collections.singleton("org/Test.class"), Collections.emptySet()); assertTrue(filter.isFiltered("a.properties")); assertFalse(filter.isFiltered("org/Test.class")); assertTrue(filter.isFiltered("org/Test.properties")); filter = new SimpleFilter(null, Collections.emptySet(), Collections.singleton("org/Test.class")); assertFalse(filter.isFiltered("a.properties")); assertTrue(filter.isFiltered("org/Test.class")); assertFalse(filter.isFiltered("org/Test.properties")); filter = new SimpleFilter(null, Collections.singleton("**/a.properties"), Collections.emptySet()); assertFalse(filter.isFiltered("a.properties")); assertFalse(filter.isFiltered("org/a.properties")); assertFalse(filter.isFiltered("org/maven/a.properties")); assertTrue(filter.isFiltered("org/maven/a.class")); filter = new SimpleFilter(null, Collections.emptySet(), Collections.singleton("org/*")); assertFalse(filter.isFiltered("Test.class")); assertTrue(filter.isFiltered("org/Test.class")); assertFalse(filter.isFiltered("org/apache/Test.class")); filter = new SimpleFilter(null, Collections.emptySet(), Collections.singleton("org/**")); assertFalse(filter.isFiltered("Test.class")); assertTrue(filter.isFiltered("org/Test.class")); assertTrue(filter.isFiltered("org/apache/Test.class")); filter = new SimpleFilter(null, Collections.emptySet(), Collections.singleton("org/")); assertFalse(filter.isFiltered("Test.class")); assertTrue(filter.isFiltered("org/Test.class")); assertTrue(filter.isFiltered("org/apache/Test.class")); // given defaults shall be excluded and a specific include is given when filtering then only specific file must // be included final ArchiveFilter archiveFilter = mock(ArchiveFilter.class); when(archiveFilter.getIncludes()).thenReturn(Collections.singleton("specific include")); when(archiveFilter.getExcludes()).thenReturn(Collections.emptySet()); when(archiveFilter.getExcludeDefaults()).thenReturn(true); filter = new SimpleFilter(null, archiveFilter); assertFalse(filter.isFiltered("specific include")); assertTrue(filter.isFiltered("some other file matched by default include")); // given defaults shall be included and a specific include is given when filtering then all files must be // included when(archiveFilter.getExcludeDefaults()).thenReturn(false); filter = new SimpleFilter(null, archiveFilter); assertFalse(filter.isFiltered("specific include")); assertFalse(filter.isFiltered("some other file matched by default include")); } } ================================================ FILE: src/test/java/org/apache/maven/plugins/shade/mojo/ArtifactIdTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.mojo; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; /** * @author Benjamin Bentmann */ public class ArtifactIdTest { @Test public void testIdParsing() { ArtifactId id; id = new ArtifactId((String) null); assertEquals("", id.getGroupId()); id = new ArtifactId(""); assertEquals("", id.getGroupId()); id = new ArtifactId("gid"); assertEquals("gid", id.getGroupId()); assertEquals("*", id.getArtifactId()); assertEquals("*", id.getType()); assertEquals("*", id.getClassifier()); id = new ArtifactId("gid:"); assertEquals("gid", id.getGroupId()); assertEquals("", id.getArtifactId()); assertEquals("*", id.getType()); assertEquals("*", id.getClassifier()); id = new ArtifactId(":aid"); assertEquals("", id.getGroupId()); assertEquals("aid", id.getArtifactId()); assertEquals("*", id.getType()); assertEquals("*", id.getClassifier()); id = new ArtifactId("gid:aid"); assertEquals("gid", id.getGroupId()); assertEquals("aid", id.getArtifactId()); assertEquals("*", id.getType()); assertEquals("*", id.getClassifier()); id = new ArtifactId("gid:aid:"); assertEquals("gid", id.getGroupId()); assertEquals("aid", id.getArtifactId()); assertEquals("*", id.getType()); assertEquals("", id.getClassifier()); id = new ArtifactId("gid:aid:cls"); assertEquals("gid", id.getGroupId()); assertEquals("aid", id.getArtifactId()); assertEquals("*", id.getType()); assertEquals("cls", id.getClassifier()); id = new ArtifactId("gid:aid:type:cls"); assertEquals("gid", id.getGroupId()); assertEquals("aid", id.getArtifactId()); assertEquals("type", id.getType()); assertEquals("cls", id.getClassifier()); id = new ArtifactId("gid:aid::cls"); assertEquals("gid", id.getGroupId()); assertEquals("aid", id.getArtifactId()); assertEquals("", id.getType()); assertEquals("cls", id.getClassifier()); id = new ArtifactId("gid:aid::"); assertEquals("gid", id.getGroupId()); assertEquals("aid", id.getArtifactId()); assertEquals("", id.getType()); assertEquals("", id.getClassifier()); id = new ArtifactId("*:aid:type:cls"); assertEquals("*", id.getGroupId()); assertEquals("aid", id.getArtifactId()); assertEquals("type", id.getType()); assertEquals("cls", id.getClassifier()); id = new ArtifactId("gid:*:type:cls"); assertEquals("gid", id.getGroupId()); assertEquals("*", id.getArtifactId()); assertEquals("type", id.getType()); assertEquals("cls", id.getClassifier()); id = new ArtifactId("gid:aid:*:cls"); assertEquals("gid", id.getGroupId()); assertEquals("aid", id.getArtifactId()); assertEquals("*", id.getType()); assertEquals("cls", id.getClassifier()); id = new ArtifactId("gid:aid:type:*"); assertEquals("gid", id.getGroupId()); assertEquals("aid", id.getArtifactId()); assertEquals("type", id.getType()); assertEquals("*", id.getClassifier()); } @Test public void testMatches() { assertTrue(new ArtifactId("gid", "aid", "type", "cls").matches(new ArtifactId("gid:aid:type:cls"))); assertFalse(new ArtifactId("Gid", "aid", "type", "cls").matches(new ArtifactId("gid:aid:type:cls"))); assertFalse(new ArtifactId("gid", "Aid", "type", "cls").matches(new ArtifactId("gid:aid:type:cls"))); assertFalse(new ArtifactId("gid", "aid", "Type", "cls").matches(new ArtifactId("gid:aid:type:cls"))); assertFalse(new ArtifactId("gid", "aid", "type", "Cls").matches(new ArtifactId("gid:aid:type:cls"))); assertTrue(new ArtifactId("gid", "aid", "any", "cls").matches(new ArtifactId("gid:aid:cls"))); assertTrue(new ArtifactId("gid", "aid", "type", "cls").matches(new ArtifactId("gid:aid:cls"))); assertFalse(new ArtifactId("id", "aid", "type", "cls").matches(new ArtifactId("gid:aid:cls"))); assertFalse(new ArtifactId("gid", "id", "type", "cls").matches(new ArtifactId("gid:aid:cls"))); assertFalse(new ArtifactId("gid", "id", "type", "ls").matches(new ArtifactId("gid:aid:cls"))); assertTrue(new ArtifactId("gid", "aid", "type", "").matches(new ArtifactId("gid:aid"))); assertTrue(new ArtifactId("gid", "aid", "any", "tests").matches(new ArtifactId("gid:aid"))); assertFalse(new ArtifactId("id", "aid", "type", "").matches(new ArtifactId("gid:aid"))); assertFalse(new ArtifactId("gid", "id", "type", "").matches(new ArtifactId("gid:aid"))); assertTrue(new ArtifactId("gid", "aid", "type", "").matches(new ArtifactId("gid"))); assertTrue(new ArtifactId("gid", "id", "any", "any").matches(new ArtifactId("gid"))); assertFalse(new ArtifactId("id", "aid", "type", "").matches(new ArtifactId("gid"))); assertTrue(new ArtifactId("gid", "aid", "type", "cls").matches(new ArtifactId("*:aid:type:cls"))); assertTrue(new ArtifactId("any", "aid", "type", "cls").matches(new ArtifactId("*:aid:type:cls"))); assertFalse(new ArtifactId("any", "id", "type", "cls").matches(new ArtifactId("*:aid:type:cls"))); assertTrue(new ArtifactId("gid", "aid", "type", "cls").matches(new ArtifactId("gid:*:type:cls"))); assertTrue(new ArtifactId("gid", "any", "type", "cls").matches(new ArtifactId("gid:*:type:cls"))); assertFalse(new ArtifactId("id", "any", "type", "cls").matches(new ArtifactId("gid:*:type:cls"))); assertTrue(new ArtifactId("gid", "aid", "type", "cls").matches(new ArtifactId("gid:aid:*:cls"))); assertTrue(new ArtifactId("gid", "aid", "any", "cls").matches(new ArtifactId("gid:aid:*:cls"))); assertFalse(new ArtifactId("id", "aid", "any", "cls").matches(new ArtifactId("gid:aid:*:cls"))); assertTrue(new ArtifactId("gid", "aid", "type", "cls").matches(new ArtifactId("gid:aid:type:*"))); assertTrue(new ArtifactId("gid", "aid", "type", "any").matches(new ArtifactId("gid:aid:type:*"))); assertFalse(new ArtifactId("id", "aid", "type", "any").matches(new ArtifactId("gid:aid:type:*"))); assertTrue(new ArtifactId("gid", "aid", "type", "cls").matches(new ArtifactId("gid:a*d"))); assertTrue(new ArtifactId("gid", "ad", "type", "cls").matches(new ArtifactId("gid:a*d"))); assertTrue(new ArtifactId("gid", "a---d", "type", "cls").matches(new ArtifactId("gid:a*d"))); assertTrue(new ArtifactId("gid", "aid", "type", "cls").matches(new ArtifactId("gid:a?d"))); assertTrue(new ArtifactId("gid", "a-d", "type", "cls").matches(new ArtifactId("gid:a?d"))); assertFalse(new ArtifactId("gid", "ad", "type", "cls").matches(new ArtifactId("gid:a?d"))); assertFalse(new ArtifactId("gid", "a---d", "type", "cls").matches(new ArtifactId("gid:a?d"))); } } ================================================ FILE: src/test/java/org/apache/maven/plugins/shade/mojo/ArtifactSelectorTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.mojo; import java.util.Collection; import java.util.Collections; import org.junit.Test; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; /** * @author Benjamin Bentmann */ public class ArtifactSelectorTest { private ArtifactSelector newSelector(Collection includes, Collection excludes, String groupPrefix) { return new ArtifactSelector(includes, excludes, groupPrefix); } @Test public void testIsSelected() { ArtifactSelector selector; selector = newSelector(null, null, null); assertTrue(selector.isSelected(new ArtifactId("gid", "aid", "type", "cls"))); selector = newSelector(null, null, ""); assertTrue(selector.isSelected(new ArtifactId("gid", "aid", "type", "cls"))); selector = newSelector(null, null, "gid"); assertTrue(selector.isSelected(new ArtifactId("gid", "aid", "type", "cls"))); assertTrue(selector.isSelected(new ArtifactId("gid.test", "aid", "type", "cls"))); assertFalse(selector.isSelected(new ArtifactId("id", "aid", "type", "cls"))); selector = newSelector(Collections.emptySet(), Collections.emptySet(), null); assertTrue(selector.isSelected(new ArtifactId("gid", "aid", "type", "cls"))); selector = newSelector(Collections.singleton("gid:aid"), Collections.emptySet(), null); assertTrue(selector.isSelected(new ArtifactId("gid", "aid", "type", "cls"))); assertFalse(selector.isSelected(new ArtifactId("gid", "id", "type", "cls"))); selector = newSelector(Collections.emptySet(), Collections.singleton("gid:aid"), null); assertFalse(selector.isSelected(new ArtifactId("gid", "aid", "type", "cls"))); assertTrue(selector.isSelected(new ArtifactId("gid", "id", "type", "cls"))); selector = newSelector(Collections.singleton("gid:*"), Collections.singleton("*:aid"), null); assertTrue(selector.isSelected(new ArtifactId("gid", "id", "type", "cls"))); assertFalse(selector.isSelected(new ArtifactId("gid", "aid", "type", "cls"))); assertFalse(selector.isSelected(new ArtifactId("gid.test", "id", "type", "cls"))); } } ================================================ FILE: src/test/java/org/apache/maven/plugins/shade/mojo/RelativizePathTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.mojo; import java.io.File; import java.io.IOException; import org.junit.Test; import static org.junit.Assert.assertEquals; public class RelativizePathTest { static final String[] PARENTS = { "rel-path-test-files/a/pom", "rel-path-test-files/a/b/pom", "rel-path-test-files/a/b/c/pom", "rel-path-test-files/a/c/d/pom" }; static final String[] CHILDREN = { "rel-path-test-files/a/b/pom", "rel-path-test-files/a/pom", "rel-path-test-files/a/b/c1/pom", "rel-path-test-files/a/c/d/pom" }; static final String[] ANSWER = {"../pom", "b/pom", "../c/pom", "pom"}; @Test public void runTests() throws IOException { for (int x = 0; x < PARENTS.length; x++) { File parent = new File(PARENTS[x]).getCanonicalFile(); File child = new File(CHILDREN[x]).getCanonicalFile(); String answer = ANSWER[x]; String r = RelativizePath.convertToRelativePath(parent, child); assertEquals(String.format("parent %s child %s", parent.toString(), child.toString()), answer, r); } } } ================================================ FILE: src/test/java/org/apache/maven/plugins/shade/mojo/ShadeMojoTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.mojo; import java.io.File; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.DefaultArtifact; import org.apache.maven.artifact.handler.ArtifactHandler; import org.apache.maven.artifact.versioning.VersionRange; import org.apache.maven.execution.MavenExecutionRequest; import org.apache.maven.execution.MavenExecutionResult; import org.apache.maven.execution.MavenSession; import org.apache.maven.plugin.testing.AbstractMojoTestCase; import org.apache.maven.plugins.shade.ShadeRequest; import org.apache.maven.plugins.shade.Shader; import org.apache.maven.plugins.shade.filter.Filter; import org.apache.maven.plugins.shade.relocation.Relocator; import org.apache.maven.plugins.shade.relocation.SimpleRelocator; import org.apache.maven.plugins.shade.resource.ComponentsXmlResourceTransformer; import org.apache.maven.plugins.shade.resource.ManifestResourceTransformer; import org.apache.maven.plugins.shade.resource.ResourceTransformer; import org.apache.maven.project.MavenProject; import org.apache.maven.repository.internal.MavenRepositorySystemUtils; import org.codehaus.plexus.ContainerConfiguration; import org.codehaus.plexus.PlexusConstants; import org.eclipse.aether.DefaultRepositorySystemSession; import org.eclipse.aether.RepositorySystem; import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory; import org.eclipse.aether.repository.LocalRepository; import org.eclipse.aether.resolution.ArtifactRequest; import org.eclipse.aether.resolution.ArtifactResult; import static java.util.Arrays.asList; import static java.util.Collections.singletonList; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; /** * @author Jason van Zyl * @author Mauro Talevi */ public class ShadeMojoTest extends AbstractMojoTestCase { @Override protected void customizeContainerConfiguration(final ContainerConfiguration configuration) { configuration.setClassPathScanning(PlexusConstants.SCANNING_INDEX); } public void testManifestTransformerSelection() throws Exception { final ShadeMojo mojo = new ShadeMojo(); final Method m = ShadeMojo.class.getDeclaredMethod("toResourceTransformers", String.class, List.class); m.setAccessible(true); final ManifestResourceTransformer defaultTfr = new ManifestResourceTransformer() { @Override public String toString() // when test fails junit does a toString so easier to read errors this way { return "default"; } }; final ManifestResourceTransformer testsTfr1 = new ManifestResourceTransformer() { @Override public String toString() { return "t1"; } }; testsTfr1.setForShade("tests"); final ManifestResourceTransformer testsTfr2 = new ManifestResourceTransformer() { @Override public String toString() { return "t2"; } }; testsTfr2.setForShade("tests"); assertEquals(singletonList(defaultTfr), m.invoke(mojo, "jar", asList(defaultTfr, testsTfr1, testsTfr2))); assertEquals(asList(testsTfr1, testsTfr2), m.invoke(mojo, "tests", asList(defaultTfr, testsTfr1, testsTfr2))); assertEquals(asList(testsTfr1, testsTfr2), m.invoke(mojo, "tests", asList(testsTfr1, defaultTfr, testsTfr2))); assertEquals(asList(testsTfr1, testsTfr2), m.invoke(mojo, "tests", asList(testsTfr1, testsTfr2, defaultTfr))); } public void testShaderWithDefaultShadedPattern() throws Exception { shaderWithPattern(null, new File("target/foo-default.jar")); } public void testShaderWithCustomShadedPattern() throws Exception { shaderWithPattern("org/shaded/plexus/util", new File("target/foo-custom.jar")); } public void testShaderWithExclusions() throws Exception { File jarFile = new File(getBasedir(), "target/unit/foo-bar.jar"); Shader s = lookup(Shader.class); Set set = new LinkedHashSet<>(); set.add(new File(getBasedir(), "src/test/jars/test-artifact-1.0-SNAPSHOT.jar")); List relocators = new ArrayList<>(); relocators.add(new SimpleRelocator( "org.codehaus.plexus.util", "hidden", null, Arrays.asList("org.codehaus.plexus.util.xml.Xpp3Dom", "org.codehaus.plexus.util.xml.pull.*"))); List resourceTransformers = new ArrayList<>(); List filters = new ArrayList<>(); ShadeRequest shadeRequest = new ShadeRequest(); shadeRequest.setJars(set); shadeRequest.setUberJar(jarFile); shadeRequest.setFilters(filters); shadeRequest.setRelocators(relocators); shadeRequest.setResourceTransformers(resourceTransformers); s.shade(shadeRequest); try (URLClassLoader cl = new URLClassLoader(new URL[] {jarFile.toURI().toURL()})) { Class c = cl.loadClass("org.apache.maven.plugins.shade.Lib"); Field field = c.getDeclaredField("CLASS_REALM_PACKAGE_IMPORT"); assertEquals("org.codehaus.plexus.util.xml.pull", field.get(null)); Method method = c.getDeclaredMethod("getClassRealmPackageImport"); assertEquals("org.codehaus.plexus.util.xml.pull", method.invoke(null)); } } /** * Tests if a Filter is installed correctly, also if createSourcesJar is set to true. * * @throws Exception */ public void testShadeWithFilter() throws Exception { // create and configure MavenProject MavenProject project = new MavenProject(); ArtifactHandler artifactHandler = lookup(ArtifactHandler.class); Artifact artifact = new DefaultArtifact( "org.apache.myfaces.core", "myfaces-impl", VersionRange.createFromVersion("2.0.1-SNAPSHOT"), "compile", "jar", null, artifactHandler); artifact.setFile(new File("myfaces-impl-2.0.1-SNAPSHOT.jar")); project.setArtifact(artifact); ShadeMojo mojo = (ShadeMojo) lookupConfiguredMojo(project, "shade"); DefaultRepositorySystemSession repositorySystemSession = MavenRepositorySystemUtils.newSession(); repositorySystemSession.setLocalRepositoryManager(new SimpleLocalRepositoryManagerFactory() .newInstance(repositorySystemSession, new LocalRepository(new File("target/local-repo/")))); MavenSession mavenSession = new MavenSession( getContainer(), repositorySystemSession, mock(MavenExecutionRequest.class), mock(MavenExecutionResult.class)); setVariableValueToObject(mojo, "session", mavenSession); // set createSourcesJar = true setVariableValueToObject(mojo, "createSourcesJar", true); RepositorySystem repositorySystem = mock(RepositorySystem.class); setVariableValueToObject(mojo, "repositorySystem", repositorySystem); ArtifactResult artifactResult = new ArtifactResult( new ArtifactRequest(mock(org.eclipse.aether.artifact.Artifact.class), Collections.emptyList(), "")); org.eclipse.aether.artifact.Artifact result = new org.eclipse.aether.artifact.DefaultArtifact( "org.apache.myfaces.core:myfaces-impl:jar:sources:2.0.1-SNAPSHOT") .setFile(new File("myfaces-impl-2.0.1-SNAPSHOT-sources.jar")); artifactResult.setArtifact(result); when(repositorySystem.resolveArtifact(eq(mavenSession.getRepositorySession()), any(ArtifactRequest.class))) .thenReturn(artifactResult); // create and configure the ArchiveFilter ArchiveFilter archiveFilter = new ArchiveFilter(); Field archiveFilterArtifact = ArchiveFilter.class.getDeclaredField("artifact"); archiveFilterArtifact.setAccessible(true); archiveFilterArtifact.set(archiveFilter, "org.apache.myfaces.core:myfaces-impl"); // add ArchiveFilter to mojo Field filtersField = ShadeMojo.class.getDeclaredField("filters"); filtersField.setAccessible(true); filtersField.set(mojo, new ArchiveFilter[] {archiveFilter}); // invoke getFilters() Method getFilters = ShadeMojo.class.getDeclaredMethod("getFilters", List.class); getFilters.setAccessible(true); List filters = (List) getFilters.invoke(mojo, Collections.emptyList()); // assertions - there must be one filter assertEquals(1, filters.size()); // the filter must be able to filter the binary and the sources jar Filter filter = filters.get(0); assertTrue(filter.canFilter(new File("myfaces-impl-2.0.1-SNAPSHOT.jar"))); // binary jar assertTrue(filter.canFilter(new File("myfaces-impl-2.0.1-SNAPSHOT-sources.jar"))); // sources jar } public void shaderWithPattern(String shadedPattern, File jar) throws Exception { Shader s = lookup(Shader.class); Set set = new LinkedHashSet<>(); set.add(new File(getBasedir(), "src/test/jars/test-project-1.0-SNAPSHOT.jar")); set.add(new File(getBasedir(), "src/test/jars/plexus-utils-1.4.1.jar")); List relocators = new ArrayList<>(); relocators.add(new SimpleRelocator( "org/codehaus/plexus/util", shadedPattern, null, Arrays.asList("org/codehaus/plexus/util/xml/Xpp3Dom", "org/codehaus/plexus/util/xml/pull.*"))); List resourceTransformers = new ArrayList<>(); resourceTransformers.add(new ComponentsXmlResourceTransformer()); List filters = new ArrayList<>(); ShadeRequest shadeRequest = new ShadeRequest(); shadeRequest.setJars(set); shadeRequest.setUberJar(jar); shadeRequest.setFilters(filters); shadeRequest.setRelocators(relocators); shadeRequest.setResourceTransformers(resourceTransformers); s.shade(shadeRequest); } } ================================================ FILE: src/test/java/org/apache/maven/plugins/shade/relocation/SimpleRelocatorParameterTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.relocation; import java.util.Collections; import org.junit.Test; import static org.junit.Assert.fail; public class SimpleRelocatorParameterTest { @Test public void testThatNullShadedPatternInConstructorShouldNotThrowNullPointerException() { constructThenFailOnNullPointerException("", null); } private void constructThenFailOnNullPointerException(String pattern, String shadedPattern) { try { new SimpleRelocator( pattern, shadedPattern, Collections.emptyList(), Collections.emptyList()); } catch (NullPointerException e) { fail("Constructor should not throw null pointer exceptions"); } // any other exception leads to test failure as well } } ================================================ FILE: src/test/java/org/apache/maven/plugins/shade/relocation/SimpleRelocatorTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.relocation; import java.util.Arrays; import java.util.Collections; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; /** * Test for {@link SimpleRelocator}. * * @author Benjamin Bentmann * */ public class SimpleRelocatorTest { @Test public void testNoNpeRelocateClass() { new SimpleRelocator("foo", "bar", null, null, true).relocateClass("foo"); } @Test public void testCanRelocatePath() { SimpleRelocator relocator; relocator = new SimpleRelocator("org.foo", null, null, null); assertTrue(relocator.canRelocatePath("org/foo/Class")); assertTrue(relocator.canRelocatePath("org/foo/Class.class")); assertTrue(relocator.canRelocatePath("org/foo/bar/Class")); assertTrue(relocator.canRelocatePath("org/foo/bar/Class.class")); assertFalse(relocator.canRelocatePath("com/foo/bar/Class")); assertFalse(relocator.canRelocatePath("com/foo/bar/Class.class")); assertFalse(relocator.canRelocatePath("org/Foo/Class")); assertFalse(relocator.canRelocatePath("org/Foo/Class.class")); relocator = new SimpleRelocator( "org.foo", null, null, Arrays.asList("org.foo.Excluded", "org.foo.public.*", "org.foo.Public*Stuff")); assertTrue(relocator.canRelocatePath("org/foo/Class")); assertTrue(relocator.canRelocatePath("org/foo/Class.class")); assertTrue(relocator.canRelocatePath("org/foo/excluded")); assertFalse(relocator.canRelocatePath("org/foo/Excluded")); assertFalse(relocator.canRelocatePath("org/foo/Excluded.class")); assertFalse(relocator.canRelocatePath("org/foo/public")); assertFalse(relocator.canRelocatePath("org/foo/public/Class")); assertFalse(relocator.canRelocatePath("org/foo/public/Class.class")); assertTrue(relocator.canRelocatePath("org/foo/publicRELOC/Class")); assertTrue(relocator.canRelocatePath("org/foo/PrivateStuff")); assertTrue(relocator.canRelocatePath("org/foo/PrivateStuff.class")); assertFalse(relocator.canRelocatePath("org/foo/PublicStuff")); assertFalse(relocator.canRelocatePath("org/foo/PublicStuff.class")); assertFalse(relocator.canRelocatePath("org/foo/PublicUtilStuff")); assertFalse(relocator.canRelocatePath("org/foo/PublicUtilStuff.class")); } @Test public void testCanRelocateClass() { SimpleRelocator relocator; relocator = new SimpleRelocator("org.foo", null, null, null); assertTrue(relocator.canRelocateClass("org.foo.Class")); assertTrue(relocator.canRelocateClass("org.foo.bar.Class")); assertFalse(relocator.canRelocateClass("com.foo.bar.Class")); assertFalse(relocator.canRelocateClass("org.Foo.Class")); relocator = new SimpleRelocator( "org.foo", null, null, Arrays.asList("org.foo.Excluded", "org.foo.public.*", "org.foo.Public*Stuff")); assertTrue(relocator.canRelocateClass("org.foo.Class")); assertTrue(relocator.canRelocateClass("org.foo.excluded")); assertFalse(relocator.canRelocateClass("org.foo.Excluded")); assertFalse(relocator.canRelocateClass("org.foo.public")); assertFalse(relocator.canRelocateClass("org.foo.public.Class")); assertTrue(relocator.canRelocateClass("org.foo.publicRELOC.Class")); assertTrue(relocator.canRelocateClass("org.foo.PrivateStuff")); assertFalse(relocator.canRelocateClass("org.foo.PublicStuff")); assertFalse(relocator.canRelocateClass("org.foo.PublicUtilStuff")); } @Test public void testCanRelocateRawString() { SimpleRelocator relocator; relocator = new SimpleRelocator("org/foo", null, null, null, true); assertTrue(relocator.canRelocatePath("(I)org/foo/bar/Class;")); relocator = new SimpleRelocator("^META-INF/org.foo.xml$", null, null, null, true); assertTrue(relocator.canRelocatePath("META-INF/org.foo.xml")); } // MSHADE-119, make sure that the easy part of this works. @Test public void testCanRelocateAbsClassPath() { SimpleRelocator relocator = new SimpleRelocator("org.apache.velocity", "org.apache.momentum", null, null); assertEquals( "/org/apache/momentum/mass.properties", relocator.relocatePath("/org/apache/velocity/mass.properties")); } @Test public void testCanRelocateAbsClassPathWithExcludes() { SimpleRelocator relocator = new SimpleRelocator( "org/apache/velocity", "org/apache/momentum", null, Arrays.asList("org/apache/velocity/excluded/*")); assertTrue(relocator.canRelocatePath("/org/apache/velocity/mass.properties")); assertTrue(relocator.canRelocatePath("org/apache/velocity/mass.properties")); assertFalse(relocator.canRelocatePath("/org/apache/velocity/excluded/mass.properties")); assertFalse(relocator.canRelocatePath("org/apache/velocity/excluded/mass.properties")); } @Test public void testCanRelocateAbsClassPathWithIncludes() { SimpleRelocator relocator = new SimpleRelocator( "org/apache/velocity", "org/apache/momentum", Arrays.asList("org/apache/velocity/included/*"), null); assertFalse(relocator.canRelocatePath("/org/apache/velocity/mass.properties")); assertFalse(relocator.canRelocatePath("org/apache/velocity/mass.properties")); assertTrue(relocator.canRelocatePath("/org/apache/velocity/included/mass.properties")); assertTrue(relocator.canRelocatePath("org/apache/velocity/included/mass.properties")); } @Test public void testRelocatePath() { SimpleRelocator relocator; relocator = new SimpleRelocator("org.foo", null, null, null); assertEquals("hidden/org/foo/bar/Class.class", relocator.relocatePath("org/foo/bar/Class.class")); relocator = new SimpleRelocator("org.foo", "private.stuff", null, null); assertEquals("private/stuff/bar/Class.class", relocator.relocatePath("org/foo/bar/Class.class")); } @Test public void testRelocateClass() { SimpleRelocator relocator; relocator = new SimpleRelocator("org.foo", null, null, null); assertEquals("hidden.org.foo.bar.Class", relocator.relocateClass("org.foo.bar.Class")); relocator = new SimpleRelocator("org.foo", "private.stuff", null, null); assertEquals("private.stuff.bar.Class", relocator.relocateClass("org.foo.bar.Class")); // make sure that "." does not match "x" in "orgxfoo.bar.Class" assertEquals("orgxfoo.bar.Class", relocator.relocateClass("orgxfoo.bar.Class")); } @Test public void testRelocateAllClasses() { SimpleRelocator relocator; relocator = new SimpleRelocator("org.foo", null, null, null); assertEquals( "hidden.org.foo.bar.Class, hidden.hidden.org.foo.bar.Class and hidden.org.foo.bar.Class", relocator.relocateAllClasses("org.foo.bar.Class, hidden.org.foo.bar.Class and org.foo.bar.Class")); relocator = new SimpleRelocator("org.foo", "private.stuff", null, null); assertEquals( "private.stuff.bar.Class, private.stuff.bar.Class and private.stuff.bar.Class", relocator.relocateAllClasses("org.foo.bar.Class, private.stuff.bar.Class and org.foo.bar.Class")); // make sure that "." does not match "x" in "orgxfoo.bar.Class" assertEquals("orgxfoo.bar.Class", relocator.relocateClass("orgxfoo.bar.Class")); } @Test public void testRelocateRawString() { SimpleRelocator relocator; relocator = new SimpleRelocator("Lorg/foo", "Lhidden/org/foo", null, null, true); assertEquals("(I)Lhidden/org/foo/bar/Class;", relocator.relocatePath("(I)Lorg/foo/bar/Class;")); relocator = new SimpleRelocator("^META-INF/org.foo.xml$", "META-INF/hidden.org.foo.xml", null, null, true); assertEquals("META-INF/hidden.org.foo.xml", relocator.relocatePath("META-INF/org.foo.xml")); } @Test public void testRelocateMavenFiles() { SimpleRelocator relocator = new SimpleRelocator( "META-INF/maven", "META-INF/shade/maven", null, Collections.singletonList("META-INF/maven/com.foo.bar/artifactId/pom.*")); assertFalse(relocator.canRelocatePath("META-INF/maven/com.foo.bar/artifactId/pom.properties")); assertFalse(relocator.canRelocatePath("META-INF/maven/com.foo.bar/artifactId/pom.xml")); assertTrue(relocator.canRelocatePath("META-INF/maven/com/foo/bar/artifactId/pom.properties")); assertTrue(relocator.canRelocatePath("META-INF/maven/com/foo/bar/artifactId/pom.xml")); assertTrue(relocator.canRelocatePath("META-INF/maven/com-foo-bar/artifactId/pom.properties")); assertTrue(relocator.canRelocatePath("META-INF/maven/com-foo-bar/artifactId/pom.xml")); } private static final String SOURCE_FILE = "package org.apache.maven.hello;\n" + "package org.objectweb.asm;\n" + "\n" + "import foo.bar.Bar;\n" + "import zot.baz.Baz;\n" + "import org.apache.maven.exclude1.Ex1;\n" + "import org.apache.maven.exclude1.a.b.Ex1AB;\n" + "import org.apache.maven.sub.exclude2.Ex2;\n" + "import org.apache.maven.sub.exclude2.c.d.Ex2CD;\n" + "import org.apache.maven.In;\n" + "import org.apache.maven.e.InE;\n" + "import org.apache.maven.f.g.InFG;\n" + "import java.io.IOException;\n" + "\n" + "/**\n" + " * Also check out {@link org.apache.maven.hello.OtherClass} and {@link\n" + " * org.apache.maven.hello.YetAnotherClass}\n" + " */\n" + "public class MyClass {\n" + " private org.apache.maven.exclude1.x.X myX;\n" + " private org.apache.maven.h.H h;\n" + " private String ioInput;\n" + "\n" + " /** Javadoc, followed by default visibility method with fully qualified return type */\n" + " org.apache.maven.MyReturnType doSomething( org.apache.maven.Bar bar, org.objectweb.asm.sub.Something something) {\n" + " org.apache.maven.Bar bar;\n" + " org.objectweb.asm.sub.Something something;\n" + " String io, val;\n" + " String noRelocation = \"NoWordBoundaryXXXorg.apache.maven.In\";\n" + " String relocationPackage = \"org.apache.maven.In\";\n" + " String relocationPath = \"org/apache/maven/In\";\n" + " }\n" + "}\n"; private static final String RELOCATED_FILE = "package com.acme.maven.hello;\n" + "package aj.org.objectweb.asm;\n" + "\n" + "import foo.bar.Bar;\n" + "import zot.baz.Baz;\n" + "import org.apache.maven.exclude1.Ex1;\n" + "import org.apache.maven.exclude1.a.b.Ex1AB;\n" + "import org.apache.maven.sub.exclude2.Ex2;\n" + "import org.apache.maven.sub.exclude2.c.d.Ex2CD;\n" + "import com.acme.maven.In;\n" + "import com.acme.maven.e.InE;\n" + "import com.acme.maven.f.g.InFG;\n" + "import java.io.IOException;\n" + "\n" + "/**\n" + " * Also check out {@link com.acme.maven.hello.OtherClass} and {@link\n" + " * com.acme.maven.hello.YetAnotherClass}\n" + " */\n" + "public class MyClass {\n" + " private org.apache.maven.exclude1.x.X myX;\n" + " private com.acme.maven.h.H h;\n" + " private String ioInput;\n" + "\n" + " /** Javadoc, followed by default visibility method with fully qualified return type */\n" + " com.acme.maven.MyReturnType doSomething( com.acme.maven.Bar bar, aj.org.objectweb.asm.sub.Something something) {\n" + " com.acme.maven.Bar bar;\n" + " aj.org.objectweb.asm.sub.Something something;\n" + " String io, val;\n" + " String noRelocation = \"NoWordBoundaryXXXorg.apache.maven.In\";\n" + " String relocationPackage = \"com.acme.maven.In\";\n" + " String relocationPath = \"com/acme/maven/In\";\n" + " }\n" + "}\n"; @Test public void testRelocateSourceWithExcludesRaw() { SimpleRelocator relocator = new SimpleRelocator( "org.apache.maven", "com.acme.maven", Arrays.asList("foo.bar", "zot.baz"), Arrays.asList("irrelevant.exclude", "org.apache.maven.exclude1", "org.apache.maven.sub.exclude2"), true); assertEquals(SOURCE_FILE, relocator.applyToSourceContent(SOURCE_FILE)); } @Test public void testRelocateSourceWithExcludes() { // Main relocator with in-/excludes SimpleRelocator relocator = new SimpleRelocator( "org.apache.maven", "com.acme.maven", Arrays.asList("foo.bar", "zot.baz"), Arrays.asList("irrelevant.exclude", "org.apache.maven.exclude1", "org.apache.maven.sub.exclude2")); // Make sure not to replace variables 'io' and 'ioInput', package 'java.io' SimpleRelocator ioRelocator = new SimpleRelocator("io", "shaded.io", null, null); // Check corner case which was not working in PR #100 SimpleRelocator asmRelocator = new SimpleRelocator("org.objectweb.asm", "aj.org.objectweb.asm", null, null); // Make sure not to replace 'foo' package by path-like 'shaded/foo' SimpleRelocator fooRelocator = new SimpleRelocator("foo", "shaded.foo", null, Arrays.asList("foo.bar")); assertEquals( RELOCATED_FILE, fooRelocator.applyToSourceContent(asmRelocator.applyToSourceContent( ioRelocator.applyToSourceContent(relocator.applyToSourceContent(SOURCE_FILE))))); } } ================================================ FILE: src/test/java/org/apache/maven/plugins/shade/resource/ApacheLicenseResourceTransformerTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.resource; import java.util.Locale; import org.junit.Before; import org.junit.Test; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; /** * Test for {@link ApacheLicenseResourceTransformer}. * * @author Benjamin Bentmann */ public class ApacheLicenseResourceTransformerTest { private ApacheLicenseResourceTransformer transformer; static { /* * NOTE: The Turkish locale has an usual case transformation for the letters "I" and "i", making it a prime * choice to test for improper case-less string comparisions. */ Locale.setDefault(new Locale("tr")); } @Before public void setUp() { transformer = new ApacheLicenseResourceTransformer(); } @Test public void testCanTransformResource() { assertTrue(transformer.canTransformResource("META-INF/LICENSE")); assertTrue(transformer.canTransformResource("META-INF/LICENSE.TXT")); assertTrue(transformer.canTransformResource("META-INF/LICENSE.md")); assertTrue(transformer.canTransformResource("META-INF/License.txt")); assertTrue(transformer.canTransformResource("META-INF/License.md")); assertFalse(transformer.canTransformResource("META-INF/MANIFEST.MF")); } } ================================================ FILE: src/test/java/org/apache/maven/plugins/shade/resource/ApacheNoticeResourceTransformerTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.resource; import java.io.ByteArrayInputStream; import java.io.IOException; import java.util.Collections; import java.util.List; import java.util.Locale; import org.apache.maven.plugins.shade.relocation.Relocator; import org.junit.Before; import org.junit.Test; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; /** * Test for {@link ApacheNoticeResourceTransformer}. * * @author Benjamin Bentmann */ public class ApacheNoticeResourceTransformerTest { private static final String NOTICE_RESOURCE = "META-INF/NOTICE"; private ApacheNoticeResourceTransformer transformer; static { /* * NOTE: The Turkish locale has an usual case transformation for the letters "I" and "i", making it a prime * choice to test for improper case-less string comparisions. */ Locale.setDefault(new Locale("tr")); } @Before public void setUp() { transformer = new ApacheNoticeResourceTransformer(); } @Test public void testCanTransformResource() { assertTrue(transformer.canTransformResource("META-INF/NOTICE")); assertTrue(transformer.canTransformResource("META-INF/NOTICE.TXT")); assertTrue(transformer.canTransformResource("META-INF/NOTICE.md")); assertTrue(transformer.canTransformResource("META-INF/Notice.txt")); assertTrue(transformer.canTransformResource("META-INF/Notice.md")); assertFalse(transformer.canTransformResource("META-INF/MANIFEST.MF")); } @Test public void testNoParametersShouldNotThrowNullPointerWhenNoInput() throws IOException { processAndFailOnNullPointer(""); } @Test public void testNoParametersShouldNotThrowNullPointerWhenNoLinesOfInput() throws IOException { processAndFailOnNullPointer("Some notice text"); } @Test public void testNoParametersShouldNotThrowNullPointerWhenOneLineOfInput() throws IOException { processAndFailOnNullPointer("Some notice text\n"); } @Test public void testNoParametersShouldNotThrowNullPointerWhenTwoLinesOfInput() throws IOException { processAndFailOnNullPointer("Some notice text\nSome notice text\n"); } @Test public void testNoParametersShouldNotThrowNullPointerWhenLineStartsWithSlashSlash() throws IOException { processAndFailOnNullPointer("Some notice text\n//Some notice text\n"); } @Test public void testNoParametersShouldNotThrowNullPointerWhenLineIsSlashSlash() throws IOException { processAndFailOnNullPointer("//\n"); } @Test public void testNoParametersShouldNotThrowNullPointerWhenLineIsEmpty() throws IOException { processAndFailOnNullPointer("\n"); } private void processAndFailOnNullPointer(final String noticeText) throws IOException { try { final ByteArrayInputStream noticeInputStream = new ByteArrayInputStream(noticeText.getBytes()); final List emptyList = Collections.emptyList(); transformer.processResource(NOTICE_RESOURCE, noticeInputStream, emptyList, 0); noticeInputStream.close(); } catch (NullPointerException e) { fail("Null pointer should not be thrown when no parameters are set."); } } } ================================================ FILE: src/test/java/org/apache/maven/plugins/shade/resource/AppendingTransformerTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.resource; import java.util.Locale; import org.junit.Before; import org.junit.Test; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; /** * Test for {@link AppendingTransformer}. * * @author Benjamin Bentmann */ public class AppendingTransformerTest { private AppendingTransformer transformer; static { /* * NOTE: The Turkish locale has an usual case transformation for the letters "I" and "i", making it a prime * choice to test for improper case-less string comparisions. */ Locale.setDefault(new Locale("tr")); } @Before public void setUp() { transformer = new AppendingTransformer(); } @Test public void testCanTransformResource() { transformer.resource = "abcdefghijklmnopqrstuvwxyz"; assertTrue(transformer.canTransformResource("abcdefghijklmnopqrstuvwxyz")); assertTrue(transformer.canTransformResource("ABCDEFGHIJKLMNOPQRSTUVWXYZ")); assertFalse(transformer.canTransformResource("META-INF/MANIFEST.MF")); } } ================================================ FILE: src/test/java/org/apache/maven/plugins/shade/resource/ComponentsXmlResourceTransformerTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.resource; import java.io.InputStream; import java.util.Collections; import org.apache.maven.plugins.shade.relocation.Relocator; import org.codehaus.plexus.util.IOUtil; import org.custommonkey.xmlunit.Diff; import org.custommonkey.xmlunit.XMLAssert; import org.custommonkey.xmlunit.XMLUnit; import org.junit.Before; import org.junit.Test; /** * Test for {@link ComponentsXmlResourceTransformer}. * * @author Brett Porter * */ public class ComponentsXmlResourceTransformerTest { private ComponentsXmlResourceTransformer transformer; @Before public void setUp() { this.transformer = new ComponentsXmlResourceTransformer(); } @Test public void testConfigurationMerging() throws Exception { XMLUnit.setNormalizeWhitespace(true); InputStream resourceAsStream = getClass().getResourceAsStream("/components-1.xml"); transformer.processResource("components-1.xml", resourceAsStream, Collections.emptyList(), 0); resourceAsStream.close(); InputStream resourceAsStream1 = getClass().getResourceAsStream("/components-2.xml"); transformer.processResource("components-1.xml", resourceAsStream1, Collections.emptyList(), 0); resourceAsStream1.close(); final InputStream resourceAsStream2 = getClass().getResourceAsStream("/components-expected.xml"); Diff diff = XMLUnit.compareXML( IOUtil.toString(resourceAsStream2, "UTF-8"), IOUtil.toString(transformer.getTransformedResource(), "UTF-8")); // assertEquals( IOUtil.toString( getClass().getResourceAsStream( "/components-expected.xml" ), "UTF-8" ), // IOUtil.toString( transformer.getTransformedResource(), "UTF-8" ).replaceAll("\r\n", "\n") ); resourceAsStream2.close(); XMLAssert.assertXMLIdentical(diff, true); } } ================================================ FILE: src/test/java/org/apache/maven/plugins/shade/resource/GroovyResourceTransformerTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.resource; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.util.Collections; import java.util.Properties; import java.util.jar.JarFile; import java.util.jar.JarOutputStream; import java.util.zip.ZipEntry; import org.apache.maven.plugins.shade.relocation.Relocator; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; /** * Test for {@link GroovyResourceTransformer}. * */ public class GroovyResourceTransformerTest { private static InputStream stream(Properties props) throws Exception { ByteArrayOutputStream baos = new ByteArrayOutputStream(); props.store(baos, null); return new ByteArrayInputStream(baos.toByteArray()); } private static InputStream module( String name, String version, String extensionClasses, String staticExtensionClasses) throws Exception { Properties desc = new Properties(); desc.setProperty("moduleName", name); desc.setProperty("moduleVersion", version); if (extensionClasses != null) { desc.setProperty("extensionClasses", extensionClasses); } if (staticExtensionClasses != null) { desc.setProperty("staticExtensionClasses", staticExtensionClasses); } return stream(desc); } private static Properties transform(GroovyResourceTransformer transformer) throws Exception { File tempJar = File.createTempFile("shade.", ".jar"); tempJar.deleteOnExit(); try (FileOutputStream fos = new FileOutputStream(tempJar); JarOutputStream jaos = new JarOutputStream(fos)) { transformer.modifyOutputStream(jaos); } Properties desc = null; try (JarFile jar = new JarFile(tempJar)) { ZipEntry entry = jar.getEntry(GroovyResourceTransformer.EXT_MODULE_NAME); if (entry != null) { desc = new Properties(); desc.load(jar.getInputStream(entry)); } } return desc; } @Test public void testFilter() { GroovyResourceTransformer transformer = new GroovyResourceTransformer(); assertTrue(transformer.canTransformResource(GroovyResourceTransformer.EXT_MODULE_NAME)); assertTrue(transformer.canTransformResource(GroovyResourceTransformer.EXT_MODULE_NAME_LEGACY)); assertFalse(transformer.canTransformResource("somethingElse")); assertFalse(transformer.canTransformResource(JarFile.MANIFEST_NAME)); } @Test public void testEmpty() throws Exception { GroovyResourceTransformer transformer = new GroovyResourceTransformer(); assertFalse(transformer.hasTransformedResource()); assertNull(transform(transformer)); } @Test public void testSpecifyModuleName() throws Exception { GroovyResourceTransformer transformer = new GroovyResourceTransformer(); transformer.setExtModuleName("the-module-name"); transformer.setExtModuleVersion("2.0"); transformer.processResource( GroovyResourceTransformer.EXT_MODULE_NAME, module("mod1", "1.0", "some.ext", "some.staticExt"), Collections.emptyList(), 0); Properties desc = transform(transformer); assertEquals("the-module-name", desc.getProperty("moduleName")); assertEquals("2.0", desc.getProperty("moduleVersion")); assertEquals("some.ext", desc.getProperty("extensionClasses")); assertEquals("some.staticExt", desc.getProperty("staticExtensionClasses")); } @Test public void testConcatenation() throws Exception { GroovyResourceTransformer transformer = new GroovyResourceTransformer(); transformer.processResource( GroovyResourceTransformer.EXT_MODULE_NAME, module("mod1", "1.0", "some.ext1", null), Collections.emptyList(), 0); transformer.processResource( GroovyResourceTransformer.EXT_MODULE_NAME, module("mod2", "1.0", null, "some.staticExt1"), Collections.emptyList(), 0); transformer.processResource( GroovyResourceTransformer.EXT_MODULE_NAME, module("mod3", "1.0", "", ""), Collections.emptyList(), 0); transformer.processResource( GroovyResourceTransformer.EXT_MODULE_NAME, module("mod4", "1.0", "some.ext2", "some.staticExt2"), Collections.emptyList(), 0); Properties desc = transform(transformer); assertEquals("no-module-name", desc.getProperty("moduleName")); assertEquals("1.0", desc.getProperty("moduleVersion")); assertEquals("some.ext1,some.ext2", desc.getProperty("extensionClasses")); assertEquals("some.staticExt1,some.staticExt2", desc.getProperty("staticExtensionClasses")); } } ================================================ FILE: src/test/java/org/apache/maven/plugins/shade/resource/ManifestResourceTransformerTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.resource; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.jar.Attributes; import java.util.jar.JarFile; import java.util.jar.JarInputStream; import java.util.jar.JarOutputStream; import java.util.jar.Manifest; import org.apache.maven.plugins.shade.relocation.Relocator; import org.apache.maven.plugins.shade.relocation.SimpleRelocator; import org.junit.Before; import org.junit.Test; import static org.junit.Assert.assertEquals; public class ManifestResourceTransformerTest { private ManifestResourceTransformer transformer; @Before public void setUp() { transformer = new ManifestResourceTransformer(); } private Manifest createTestManifest() { final Manifest manifest = new Manifest(); final Attributes attributes = manifest.getMainAttributes(); attributes.put(Attributes.Name.MANIFEST_VERSION, "1.0"); attributes.putValue( "Export-Package", "javax.decorator;version=\"2.0\";uses:=\"javax.enterprise.inject\"," + "javax.enterprise.context;version=\"2.0\";uses:=\"javax.enterprise.util,javax.inject\""); attributes.putValue("Import-Package", "javax.el,javax.enterprise.context;version=\"[2.0,3)\""); attributes.putValue( "Provide-Capability", "osgi.contract;osgi.contract=JavaCDI;uses:=\"" + "javax.enterprise.context,javax.enterprise.context.spi,javax.enterprise.context.control," + "javax.enterprise.util,javax.enterprise.inject,javax.enterprise.inject.spi," + "javax.enterprise.inject.spi.configurator,javax.enterprise.inject.literal," + "javax.enterprise.inject.se,javax.enterprise.event,javax.decorator\";" + "version:List=\"2.0,1.2,1.1,1.0\""); attributes.putValue( "Require-Capability", "osgi.serviceloader;" + "filter:=\"(osgi.serviceloader=javax.enterprise.inject.se.SeContainerInitializer)\";" + "cardinality:=multiple," + "osgi.serviceloader;" + "filter:=\"(osgi.serviceloader=javax.enterprise.inject.spi.CDIProvider)\";" + "cardinality:=multiple,osgi.extender;" + "filter:=\"(osgi.extender=osgi.serviceloader.processor)\"," + "osgi.contract;osgi.contract=JavaEL;filter:=\"(&(osgi.contract=JavaEL)(version=2.2.0))\"," + "osgi.contract;osgi.contract=JavaInterceptor;" + "filter:=\"(&(osgi.contract=JavaInterceptor)(version=1.2.0))\"," + "osgi.contract;osgi.contract=JavaInject;" + "filter:=\"(&(osgi.contract=JavaInject)(version=1.0.0))\"," + "osgi.ee;filter:=\"(&(osgi.ee=JavaSE)(version=1.8))\""); return manifest; } @Test public void rewriteDefaultAttributes() throws Exception { final Manifest manifest = createTestManifest(); List relocators = Collections.singletonList(new SimpleRelocator( "javax", "jakarta", Collections.emptyList(), Collections.emptyList())); final ByteArrayOutputStream out = transform(manifest, relocators); try (JarInputStream jis = new JarInputStream(new ByteArrayInputStream(out.toByteArray()))) { Attributes attrs = jis.getManifest().getMainAttributes(); assertEquals( "jakarta.decorator;version=\"2.0\";uses:=\"jakarta.enterprise.inject\"," + "jakarta.enterprise.context;version=\"2.0\";uses:=\"jakarta.enterprise.util," + "jakarta.inject\"", attrs.getValue("Export-Package")); assertEquals("jakarta.el,jakarta.enterprise.context;version=\"[2.0,3)\"", attrs.getValue("Import-Package")); assertEquals( "osgi.contract;osgi.contract=JavaCDI;" + "uses:=\"jakarta.enterprise.context," + "jakarta.enterprise.context.spi,jakarta.enterprise.context.control," + "jakarta.enterprise.util,jakarta.enterprise.inject,jakarta.enterprise.inject.spi," + "jakarta.enterprise.inject.spi.configurator,jakarta.enterprise.inject.literal," + "jakarta.enterprise.inject.se,jakarta.enterprise.event," + "jakarta.decorator\";version:List=\"2.0,1.2,1.1,1.0\"", attrs.getValue("Provide-Capability")); assertEquals( "osgi.serviceloader;" + "filter:=\"(osgi.serviceloader=jakarta.enterprise.inject.se.SeContainerInitializer)\";" + "cardinality:=multiple,osgi.serviceloader;" + "filter:=\"(osgi.serviceloader=jakarta.enterprise.inject.spi.CDIProvider)\";" + "cardinality:=multiple,osgi.extender;" + "filter:=\"(osgi.extender=osgi.serviceloader.processor)\"," + "osgi.contract;osgi.contract=JavaEL;filter:=\"(&(osgi.contract=JavaEL)(version=2.2.0))\"," + "osgi.contract;osgi.contract=JavaInterceptor;" + "filter:=\"(&(osgi.contract=JavaInterceptor)(version=1.2.0))\"," + "osgi.contract;osgi.contract=JavaInject;" + "filter:=\"(&(osgi.contract=JavaInject)(version=1.0.0))\"," + "osgi.ee;filter:=\"(&(osgi.ee=JavaSE)(version=1.8))\"", attrs.getValue("Require-Capability")); } } @Test() public void rewriteDefaultAttributesWithSameSuffix() throws Exception { final Manifest manifest = createTestManifest(); List relocators = Collections.singletonList(new SimpleRelocator( "javax", "shaded.javax", Collections.emptyList(), Collections.emptyList())); final ByteArrayOutputStream out = transform(manifest, relocators); try (JarInputStream jis = new JarInputStream(new ByteArrayInputStream(out.toByteArray()))) { Attributes attrs = jis.getManifest().getMainAttributes(); assertEquals( "shaded.javax.decorator;version=\"2.0\";uses:=\"shaded.javax.enterprise.inject\",shaded.javax.enterprise.context;version=\"2.0\";uses:=\"shaded.javax.enterprise.util,shaded.javax.inject\"", attrs.getValue("Export-Package")); assertEquals( "shaded.javax.el,shaded.javax.enterprise.context;version=\"[2.0,3)\"", attrs.getValue("Import-Package")); assertEquals( "osgi.contract;osgi.contract=JavaCDI;uses:=\"shaded.javax.enterprise.context,shaded.javax.enterprise.context.spi,shaded.javax.enterprise.context.control,shaded.javax.enterprise.util,shaded.javax.enterprise.inject,shaded.javax.enterprise.inject.spi,shaded.javax.enterprise.inject.spi.configurator,shaded.javax.enterprise.inject.literal,shaded.javax.enterprise.inject.se,shaded.javax.enterprise.event,shaded.javax.decorator\";version:List=\"2.0,1.2,1.1,1.0\"", attrs.getValue("Provide-Capability")); assertEquals( "osgi.serviceloader;filter:=\"(osgi.serviceloader=shaded.javax.enterprise.inject.se.SeContainerInitializer)\";cardinality:=multiple,osgi.serviceloader;filter:=\"(osgi.serviceloader=shaded.javax.enterprise.inject.spi.CDIProvider)\";cardinality:=multiple,osgi.extender;filter:=\"(osgi.extender=osgi.serviceloader.processor)\",osgi.contract;osgi.contract=JavaEL;filter:=\"(&(osgi.contract=JavaEL)(version=2.2.0))\",osgi.contract;osgi.contract=JavaInterceptor;filter:=\"(&(osgi.contract=JavaInterceptor)(version=1.2.0))\",osgi.contract;osgi.contract=JavaInject;filter:=\"(&(osgi.contract=JavaInject)(version=1.0.0))\",osgi.ee;filter:=\"(&(osgi.ee=JavaSE)(version=1.8))\"", attrs.getValue("Require-Capability")); } } @Test public void rewriteAdditionalAttributes() throws Exception { final Manifest manifest = new Manifest(); final Attributes attributes = manifest.getMainAttributes(); attributes.put(Attributes.Name.MANIFEST_VERSION, "1.0"); attributes.putValue("description-custom", "This jar uses javax packages"); List relocators = Collections.singletonList(new SimpleRelocator( "javax", "jakarta", Collections.emptyList(), Collections.emptyList())); transformer.setAdditionalAttributes(Arrays.asList("description-custom", "attribute-unknown")); final ByteArrayOutputStream out = transform(manifest, relocators); try (JarInputStream jis = new JarInputStream(new ByteArrayInputStream(out.toByteArray()))) { Attributes attrs = jis.getManifest().getMainAttributes(); assertEquals("This jar uses jakarta packages", attrs.getValue("description-custom")); } } private ByteArrayOutputStream transform(final Manifest manifest, List relocators) throws IOException { final ByteArrayOutputStream mboas = new ByteArrayOutputStream(); try (OutputStream mos = mboas) { manifest.write(mos); } transformer.processResource( JarFile.MANIFEST_NAME, new ByteArrayInputStream(mboas.toByteArray()), relocators, 0); final ByteArrayOutputStream out = new ByteArrayOutputStream(); try (JarOutputStream jarOutputStream = new JarOutputStream(out)) { transformer.modifyOutputStream(jarOutputStream); } return out; } } ================================================ FILE: src/test/java/org/apache/maven/plugins/shade/resource/ReproducibleResourceTransformer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.resource; import java.io.IOException; import java.io.InputStream; import java.util.List; import org.apache.maven.plugins.shade.relocation.Relocator; /** * Copy of original interface necessary to MSHADE-363_old-plugin IT: * CustomReproducibleResourceTransformer is built with ReproducibleResourceTransformer interface provided by * recent maven-shade-plugin, but older maven-shade-plugin 3.2.2 will be used at runtime in the * MSHADE-363_old-plugin IT, an older that does not provide the interface. Without the interface copy * in the custom resource transformer code, this would lead to ClassNotFoundException... * * @since 3.2.4 * @see org.apache.maven.plugins.shade.custom.CustomReproducibleResourceTransformer */ public interface ReproducibleResourceTransformer extends ResourceTransformer { void processResource(String resource, InputStream is, List relocators, long time) throws IOException; } ================================================ FILE: src/test/java/org/apache/maven/plugins/shade/resource/ResourceBundleAppendingTransformerTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.resource; import org.junit.Before; import org.junit.Test; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; public class ResourceBundleAppendingTransformerTest { private ResourceBundleAppendingTransformer transformer; @Before public void setUp() { transformer = new ResourceBundleAppendingTransformer(); } @Test public void testCanTransformResource() { transformer.setBasename("a/b/c/ButtonLabel"); assertTrue(transformer.canTransformResource("a/b/c/ButtonLabel.properties")); assertTrue(transformer.canTransformResource("a/b/c/ButtonLabel_en.properties")); assertTrue(transformer.canTransformResource("a/b/c/ButtonLabel_en_US.properties")); assertTrue(transformer.canTransformResource("a/b/c/ButtonLabel_fr.properties")); assertTrue(transformer.canTransformResource("a/b/c/ButtonLabel_fr_CA.properties")); assertTrue(transformer.canTransformResource("a/b/c/ButtonLabel_fr_CA_UNIX.properties")); assertFalse(transformer.canTransformResource("a/b/c/ButtonLabel.class")); assertFalse(transformer.canTransformResource("c/ButtonLabel.properties")); assertFalse(transformer.canTransformResource("ButtonLabel.properties")); } } ================================================ FILE: src/test/java/org/apache/maven/plugins/shade/resource/ServiceResourceTransformerTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.resource; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.jar.JarOutputStream; import org.apache.maven.plugins.shade.relocation.Relocator; import org.apache.maven.plugins.shade.relocation.SimpleRelocator; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; /** * Test for handling META-INF/service/... */ public class ServiceResourceTransformerTest { private final String newline = "\n"; private final List relocators = new ArrayList<>(); @Test public void relocatedClasses() throws Exception { SimpleRelocator relocator = new SimpleRelocator("org.foo", "borg.foo", null, Arrays.asList("org.foo.exclude.*")); relocators.add(relocator); String content = "org.foo.Service\norg.foo.exclude.OtherService\n"; byte[] contentBytes = content.getBytes(StandardCharsets.UTF_8); InputStream contentStream = new ByteArrayInputStream(contentBytes); String contentResource = "META-INF/services/org.foo.something.another"; String contentResourceShaded = "META-INF/services/borg.foo.something.another"; ServicesResourceTransformer xformer = new ServicesResourceTransformer(); xformer.processResource(contentResource, contentStream, relocators, 0); contentStream.close(); File tempJar = File.createTempFile("shade.", ".jar"); tempJar.deleteOnExit(); FileOutputStream fos = new FileOutputStream(tempJar); try (JarOutputStream jos = new JarOutputStream(fos)) { xformer.modifyOutputStream(jos); jos.close(); JarFile jarFile = new JarFile(tempJar); JarEntry jarEntry = jarFile.getJarEntry(contentResourceShaded); assertNotNull(jarEntry); try (InputStream entryStream = jarFile.getInputStream(jarEntry)) { String xformedContent = toString(entryStream, StandardCharsets.UTF_8); assertEquals("borg.foo.Service" + newline + "org.foo.exclude.OtherService" + newline, xformedContent); } finally { jarFile.close(); } } finally { tempJar.delete(); } } @Test public void mergeRelocatedFiles() throws Exception { SimpleRelocator relocator = new SimpleRelocator("org.foo", "borg.foo", null, Collections.singletonList("org.foo.exclude.*")); relocators.add(relocator); String content = "org.foo.Service" + newline + "org.foo.exclude.OtherService" + newline; String contentShaded = "borg.foo.Service" + newline + "org.foo.exclude.OtherService" + newline; byte[] contentBytes = content.getBytes(StandardCharsets.UTF_8); String contentResource = "META-INF/services/org.foo.something.another"; String contentResourceShaded = "META-INF/services/borg.foo.something.another"; ServicesResourceTransformer xformer = new ServicesResourceTransformer(); try (InputStream contentStream = new ByteArrayInputStream(contentBytes)) { xformer.processResource(contentResource, contentStream, relocators, 0); } try (InputStream contentStream = new ByteArrayInputStream(contentBytes)) { xformer.processResource(contentResourceShaded, contentStream, relocators, 0); } File tempJar = File.createTempFile("shade.", ".jar"); tempJar.deleteOnExit(); FileOutputStream fos = new FileOutputStream(tempJar); try (JarOutputStream jos = new JarOutputStream(fos)) { xformer.modifyOutputStream(jos); jos.close(); JarFile jarFile = new JarFile(tempJar); JarEntry jarEntry = jarFile.getJarEntry(contentResourceShaded); assertNotNull(jarEntry); try (InputStream entryStream = jarFile.getInputStream(jarEntry)) { String xformedContent = toString(entryStream, StandardCharsets.UTF_8); assertEquals(contentShaded, xformedContent); } finally { jarFile.close(); } } finally { tempJar.delete(); } } @Test public void concatanationAppliedMultipleTimes() throws Exception { SimpleRelocator relocator = new SimpleRelocator("org.eclipse", "org.eclipse1234", null, null); relocators.add(relocator); String content = "org.eclipse.osgi.launch.EquinoxFactory\n"; byte[] contentBytes = content.getBytes("UTF-8"); InputStream contentStream = new ByteArrayInputStream(contentBytes); String contentResource = "META-INF/services/org.osgi.framework.launch.FrameworkFactory"; ServicesResourceTransformer xformer = new ServicesResourceTransformer(); xformer.processResource(contentResource, contentStream, relocators, 0); contentStream.close(); File tempJar = File.createTempFile("shade.", ".jar"); tempJar.deleteOnExit(); FileOutputStream fos = new FileOutputStream(tempJar); try (JarOutputStream jos = new JarOutputStream(fos)) { xformer.modifyOutputStream(jos); jos.close(); JarFile jarFile = new JarFile(tempJar); JarEntry jarEntry = jarFile.getJarEntry(contentResource); assertNotNull(jarEntry); try (InputStream entryStream = jarFile.getInputStream(jarEntry)) { String xformedContent = toString(entryStream, StandardCharsets.UTF_8); assertEquals("org.eclipse1234.osgi.launch.EquinoxFactory" + newline, xformedContent); } finally { jarFile.close(); } } finally { tempJar.delete(); } } @Test public void concatenation() throws Exception { SimpleRelocator relocator = new SimpleRelocator("org.foo", "borg.foo", null, null); relocators.add(relocator); String content = "org.foo.Service\n"; byte[] contentBytes = content.getBytes(StandardCharsets.UTF_8); InputStream contentStream = new ByteArrayInputStream(contentBytes); String contentResource = "META-INF/services/org.something.another"; ServicesResourceTransformer xformer = new ServicesResourceTransformer(); xformer.processResource(contentResource, contentStream, relocators, 0); contentStream.close(); content = "org.blah.Service\n"; contentBytes = content.getBytes(StandardCharsets.UTF_8); contentStream = new ByteArrayInputStream(contentBytes); contentResource = "META-INF/services/org.something.another"; xformer.processResource(contentResource, contentStream, relocators, 0); contentStream.close(); File tempJar = File.createTempFile("shade.", ".jar"); tempJar.deleteOnExit(); FileOutputStream fos = new FileOutputStream(tempJar); try (JarOutputStream jos = new JarOutputStream(fos)) { xformer.modifyOutputStream(jos); jos.close(); JarFile jarFile = new JarFile(tempJar); JarEntry jarEntry = jarFile.getJarEntry(contentResource); assertNotNull(jarEntry); try (InputStream entryStream = jarFile.getInputStream(jarEntry)) { String xformedContent = toString(entryStream, StandardCharsets.UTF_8); // must be two lines, with our two classes. String[] classes = xformedContent.split("\r?\n"); boolean h1 = false; boolean h2 = false; for (String name : classes) { if ("org.blah.Service".equals(name)) { h1 = true; } else if ("borg.foo.Service".equals(name)) { h2 = true; } } assertTrue(h1 && h2); } finally { jarFile.close(); } } finally { tempJar.delete(); } } private static String toString(InputStream stream, Charset charset) throws IOException { ByteArrayOutputStream buffer = new ByteArrayOutputStream(); byte[] data = new byte[8192]; int read; while ((read = stream.read(data, 0, data.length)) != -1) { buffer.write(data, 0, read); } return new String(buffer.toByteArray(), charset); } } ================================================ FILE: src/test/java/org/apache/maven/plugins/shade/resource/XmlAppendingTransformerTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.resource; import java.util.Locale; import org.junit.Before; import org.junit.Test; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; /** * Test for {@link XmlAppendingTransformer}. * * @author Benjamin Bentmann * */ public class XmlAppendingTransformerTest { private XmlAppendingTransformer transformer; static { /* * NOTE: The Turkish locale has an usual case transformation for the letters "I" and "i", making it a prime * choice to test for improper case-less string comparisions. */ Locale.setDefault(new Locale("tr")); } @Before public void setUp() { transformer = new XmlAppendingTransformer(); } @Test public void testCanTransformResource() { transformer.resource = "abcdefghijklmnopqrstuvwxyz"; assertTrue(transformer.canTransformResource("abcdefghijklmnopqrstuvwxyz")); assertTrue(transformer.canTransformResource("ABCDEFGHIJKLMNOPQRSTUVWXYZ")); assertFalse(transformer.canTransformResource("META-INF/MANIFEST.MF")); } } ================================================ FILE: src/test/java/org/apache/maven/plugins/shade/resource/properties/PropertiesTransformerTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.resource.properties; import java.io.BufferedWriter; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.nio.charset.StandardCharsets; import java.util.Properties; import org.apache.maven.plugins.shade.resource.properties.io.NoCloseOutputStream; import org.apache.maven.plugins.shade.resource.properties.io.SkipPropertiesDateLineWriter; import org.apache.maven.plugins.shade.resource.rule.TransformerTesterRule; import org.apache.maven.plugins.shade.resource.rule.TransformerTesterRule.Property; import org.apache.maven.plugins.shade.resource.rule.TransformerTesterRule.Resource; import org.apache.maven.plugins.shade.resource.rule.TransformerTesterRule.TransformerTest; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; public class PropertiesTransformerTest { @Rule public final TestRule tester = new TransformerTesterRule(); @Test public void propertiesRewritingIsStable() throws IOException { final Properties properties = new SortedProperties(); properties.setProperty("a", "1"); properties.setProperty("b", "2"); final ByteArrayOutputStream os = new ByteArrayOutputStream(); final BufferedWriter writer = new SkipPropertiesDateLineWriter( new OutputStreamWriter(new NoCloseOutputStream(os), StandardCharsets.ISO_8859_1)); properties.store(writer, " Merged by maven-shade-plugin"); writer.close(); os.close(); assertEquals( "# Merged by maven-shade-plugin\n" + "a=1\n" + "b=2\n", os.toString("UTF-8").replace(System.lineSeparator(), "\n")); } @Test public void canTransform() { final PropertiesTransformer transformer = new PropertiesTransformer(); transformer.setResource("foo/bar/my.properties"); assertTrue(transformer.canTransformResource("foo/bar/my.properties")); assertFalse(transformer.canTransformResource("whatever")); } @Test @TransformerTest( transformer = PropertiesTransformer.class, configuration = @Property(name = "resource", value = "foo/bar/my.properties"), visited = { @Resource(path = "foo/bar/my.properties", content = "a=b"), @Resource(path = "foo/bar/my.properties", content = "c=d"), }, expected = @Resource(path = "foo/bar/my.properties", content = "#.*\na=b\nc=d\n")) public void mergeWithoutOverlap() {} @Test @TransformerTest( transformer = PropertiesTransformer.class, configuration = { @Property(name = "resource", value = "foo/bar/my.properties"), @Property(name = "ordinalKey", value = "priority") }, visited = { @Resource(path = "foo/bar/my.properties", content = "a=d\npriority=3"), @Resource(path = "foo/bar/my.properties", content = "a=b\npriority=1"), @Resource(path = "foo/bar/my.properties", content = "a=c\npriority=2"), }, expected = @Resource(path = "foo/bar/my.properties", content = "#.*\na=d\n")) public void mergeWithOverlap() {} @Test @TransformerTest( transformer = PropertiesTransformer.class, configuration = { @Property(name = "resource", value = "foo/bar/my.properties"), @Property(name = "alreadyMergedKey", value = "complete") }, visited = { @Resource(path = "foo/bar/my.properties", content = "a=b\ncomplete=true"), @Resource(path = "foo/bar/my.properties", content = "a=c\npriority=2"), }, expected = @Resource(path = "foo/bar/my.properties", content = "#.*\na=b\n")) public void mergeWithAlreadyMerged() {} @Test @TransformerTest( transformer = PropertiesTransformer.class, configuration = { @Property(name = "resource", value = "foo/bar/my.properties"), @Property(name = "alreadyMergedKey", value = "complete") }, visited = { @Resource(path = "foo/bar/my.properties", content = "a=b\ncomplete=true"), @Resource(path = "foo/bar/my.properties", content = "a=c\ncomplete=true"), }, expected = {}, expectedException = IllegalStateException.class) public void alreadyMergeConflict() {} } ================================================ FILE: src/test/java/org/apache/maven/plugins/shade/resource/rule/TransformerTesterRule.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade.resource.rule; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.lang.annotation.Retention; import java.lang.annotation.Target; import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.jar.JarEntry; import java.util.jar.JarInputStream; import java.util.jar.JarOutputStream; import org.apache.maven.plugins.shade.relocation.Relocator; import org.apache.maven.plugins.shade.resource.ReproducibleResourceTransformer; import org.codehaus.plexus.component.configurator.ComponentConfigurationException; import org.codehaus.plexus.component.configurator.converters.ConfigurationConverter; import org.codehaus.plexus.component.configurator.converters.lookup.ConverterLookup; import org.codehaus.plexus.component.configurator.converters.lookup.DefaultConverterLookup; import org.codehaus.plexus.component.configurator.expression.DefaultExpressionEvaluator; import org.codehaus.plexus.configuration.DefaultPlexusConfiguration; import org.codehaus.plexus.configuration.PlexusConfiguration; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.Statement; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; public class TransformerTesterRule implements TestRule { @Override public Statement apply(Statement base, Description description) { return new Statement() { @Override public void evaluate() throws Throwable { TransformerTest spec = description.getAnnotation(TransformerTest.class); if (spec == null) { base.evaluate(); return; } Map jar; try { ReproducibleResourceTransformer transformer = createTransformer(spec); visit(spec, transformer); jar = captureOutput(transformer); } catch (Exception ex) { if (Exception.class.isAssignableFrom(spec.expectedException())) { assertTrue( ex.getClass().getName(), spec.expectedException().isAssignableFrom(ex.getClass())); return; } else { throw ex; } } asserts(spec, jar); } }; } private void asserts(TransformerTest spec, Map jar) { if (spec.strictMatch() && jar.size() != spec.expected().length) { fail("Strict match test failed: " + jar); } for (final Resource expected : spec.expected()) { final String content = jar.get(expected.path()); assertNotNull(expected.path(), content); assertTrue( expected.path() + ", expected=" + expected.content() + ", actual=" + content, content.replace(System.lineSeparator(), "\n").matches(expected.content())); } } private Map captureOutput(ReproducibleResourceTransformer transformer) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); try (JarOutputStream jar = new JarOutputStream(out)) { transformer.modifyOutputStream(jar); } Map created = new HashMap<>(); try (JarInputStream jar = new JarInputStream(new ByteArrayInputStream(out.toByteArray()))) { JarEntry entry; while ((entry = jar.getNextJarEntry()) != null) { created.put(entry.getName(), read(jar)); } } return created; } private void visit(TransformerTest spec, ReproducibleResourceTransformer transformer) throws IOException { for (Resource resource : spec.visited()) { if (transformer.canTransformResource(resource.path())) { transformer.processResource( resource.path(), new ByteArrayInputStream(resource.content().getBytes(StandardCharsets.UTF_8)), Collections.emptyList(), 0); } } } private String read(JarInputStream jar) throws IOException { StringBuilder builder = new StringBuilder(); byte[] buffer = new byte[512]; int read; while ((read = jar.read(buffer)) >= 0) { builder.append(new String(buffer, 0, read)); } return builder.toString(); } private ReproducibleResourceTransformer createTransformer(TransformerTest spec) { ConverterLookup lookup = new DefaultConverterLookup(); try { ConfigurationConverter converter = lookup.lookupConverterForType(spec.transformer()); PlexusConfiguration configuration = new DefaultPlexusConfiguration("configuration"); for (Property property : spec.configuration()) { configuration.addChild(property.name(), property.value()); } return (ReproducibleResourceTransformer) converter.fromConfiguration( lookup, configuration, spec.transformer(), spec.transformer(), Thread.currentThread().getContextClassLoader(), new DefaultExpressionEvaluator()); } catch (ComponentConfigurationException e) { throw new IllegalStateException(e); } } /** * Enables to describe a test without having to implement the logic itself. */ @Target(METHOD) @Retention(RUNTIME) public @interface TransformerTest { /** * @return the list of resource the transformer will process. */ Resource[] visited(); /** * @return the expected output created by the transformer. */ Resource[] expected(); /** * @return true if only expected resources must be found. */ boolean strictMatch() default true; /** * @return type of transformer to use. */ Class transformer(); /** * @return transformer configuration. */ Property[] configuration(); /** * @return if set to an exception class it ensures it is thrown during the processing. */ Class expectedException() default Object.class; } @Target(METHOD) @Retention(RUNTIME) public @interface Property { String name(); String value(); } @Target(METHOD) @Retention(RUNTIME) public @interface Resource { String path(); String content(); } } ================================================ FILE: src/test/projects/default-config-project/pom.xml ================================================ 4.0.0 org.apache.maven.plugins.shade default-config-project default-config-project jar 1.0-SNAPSHOT http://maven.apache.org org.apache.maven.plugins.shade test-project ${pom.version} org.apache.maven.plugins maven-shade-plugin package shade ================================================ FILE: src/test/projects/no-relocation-project/pom.xml ================================================ 4.0.0 org.apache.maven.plugins.shade no-relocation-project no-relocation-project jar 1.0-SNAPSHOT http://maven.apache.org org.apache.maven.plugins.shade test-project ${pom.version} org.apache.maven.plugins maven-shade-plugin package shade classworlds:classworlds junit:junit jmock:jmock xml-apis:xml-apis ================================================ FILE: src/test/projects/pom.xml ================================================ 4.0.0 org.apache.maven.plugins.shade projects-parent projects-parent pom 1.0-SNAPSHOT http://maven.apache.org test-project no-relocation-project shaded-project shaded-renamed-project shaded-attached-project test-artifact ================================================ FILE: src/test/projects/shaded-attached-project/pom.xml ================================================ 4.0.0 org.apache.maven.plugins.shade shaded-attached-project shaded-attached-project jar 1.0-SNAPSHOT http://maven.apache.org org.apache.maven.plugins.shade test-project ${pom.version} org.apache.maven.plugins maven-shade-plugin package shade shaded-artifact true jackofall classworlds:classworlds junit:junit jmock:jmock xml-apis:xml-apis org.codehaus.plexus.util org.codehaus.plexus.util.xml.Xpp3Dom org.codehaus.plexus.util.xml.pull.* ================================================ FILE: src/test/projects/shaded-project/pom.xml ================================================ 4.0.0 org.apache.maven.plugins.shade shaded-project shaded-project jar 1.0-SNAPSHOT http://maven.apache.org org.apache.maven.plugins.shade test-project ${pom.version} org.apache.maven.plugins maven-shade-plugin package shade classworlds:classworlds junit:junit jmock:jmock xml-apis:xml-apis org.codehaus.plexus.util org.shaded.plexus.util org.codehaus.plexus.util.xml.Xpp3Dom org.codehaus.plexus.util.xml.pull.* ================================================ FILE: src/test/projects/shaded-renamed-project/pom.xml ================================================ 4.0.0 org.apache.maven.plugins.shade shaded-renamed-project shaded-renamed-project jar 1.0-SNAPSHOT http://maven.apache.org org.apache.maven.plugins.shade test-project ${pom.version} org.apache.maven.plugins maven-shade-plugin package shade renamed-artifact classworlds:classworlds junit:junit jmock:jmock xml-apis:xml-apis org.codehaus.plexus.util org.codehaus.plexus.util.xml.Xpp3Dom org.codehaus.plexus.util.xml.pull.* ================================================ FILE: src/test/projects/test-artifact/pom.xml ================================================ projects-parent org.apache.maven.plugins.shade 1.0-SNAPSHOT 4.0.0 test-artifact test-artifact 1.0-SNAPSHOT http://maven.apache.org junit junit 3.8.1 test ================================================ FILE: src/test/projects/test-artifact/src/main/java/org/apache/maven/plugins/shade/Lib.java ================================================ package org.apache.maven.plugins.shade; /* * 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. */ /** * Hello world! * */ public class Lib { // simulate the type of call for static loggers that currently fails private static final String name = new String( Lib.class.getName() ); public static final String CONSTANT = "foo.bar/baz"; // constant shouldn't be changed if "org.codehaus.plexus.util.xml.pull.*" is excluded from relocation. public static final String CLASS_REALM_PACKAGE_IMPORT = "org.codehaus.plexus.util.xml.pull"; public static String getClassRealmPackageImport() { // argument shouldn't be changed if "org.codehaus.plexus.util.xml.pull.*" is excluded from relocation. return importFrom( "org.codehaus.plexus.util.xml.pull" ); } private static String importFrom( String packageName ) { return packageName; } } ================================================ FILE: src/test/projects/test-project/pom.xml ================================================ 4.0.0 org.apache.maven.plugins.shade test-project test-project jar 1.0-SNAPSHOT http://maven.apache.org ${project.groupId} test-artifact ${project.version} org.codehaus.plexus plexus-utils 3.3.0 org.junit.jupiter junit-jupiter-api 5.14.0 test ================================================ FILE: src/test/projects/test-project/src/main/java/org/apache/maven/plugins/shade/App.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade; import org.codehaus.plexus.util.*; /** * Hello world! * */ public class App { public static void main( String[] args ) { System.out.println( "Hello World!" ); StringUtils.isEmpty( "foo" ); } } ================================================ FILE: src/test/projects/test-project/src/main/resources/META-INF/plexus/components.xml ================================================ org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout default org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout legacy org.apache.maven.artifact.repository.layout.LegacyRepositoryLayout org.apache.maven.artifact.handler.manager.ArtifactHandlerManager org.apache.maven.artifact.handler.manager.DefaultArtifactHandlerManager org.apache.maven.artifact.handler.ArtifactHandler artifactHandlers org.apache.maven.artifact.handler.ArtifactHandler ejb org.apache.maven.artifact.handler.DefaultArtifactHandler ejb jar java true org.apache.maven.artifact.handler.ArtifactHandler jar org.apache.maven.artifact.handler.DefaultArtifactHandler jar java true org.apache.maven.artifact.handler.ArtifactHandler test-jar org.apache.maven.artifact.handler.DefaultArtifactHandler tests jar test-jar jar java true org.apache.maven.artifact.handler.ArtifactHandler maven-plugin org.apache.maven.artifact.handler.DefaultArtifactHandler maven-plugin jar java true org.apache.maven.artifact.handler.ArtifactHandler pom org.apache.maven.artifact.handler.DefaultArtifactHandler pom org.apache.maven.artifact.handler.ArtifactHandler java-source org.apache.maven.artifact.handler.DefaultArtifactHandler sources java-source jar java false org.apache.maven.artifact.handler.ArtifactHandler javadoc org.apache.maven.artifact.handler.DefaultArtifactHandler javadoc javadoc jar java true org.apache.maven.artifact.handler.ArtifactHandler war org.apache.maven.artifact.handler.DefaultArtifactHandler war true java false org.apache.maven.artifact.handler.ArtifactHandler ear org.apache.maven.artifact.handler.DefaultArtifactHandler ear true java false org.apache.maven.artifact.handler.ArtifactHandler ejb-client org.apache.maven.artifact.handler.DefaultArtifactHandler ejb-client jar ejb client java true org.apache.maven.artifact.handler.ArtifactHandler par org.apache.maven.artifact.handler.DefaultArtifactHandler par java true org.apache.maven.artifact.handler.ArtifactHandler ejb3 org.apache.maven.artifact.handler.DefaultArtifactHandler ejb3 java true org.apache.maven.artifact.factory.ArtifactFactory org.apache.maven.artifact.factory.DefaultArtifactFactory org.apache.maven.artifact.handler.manager.ArtifactHandlerManager org.apache.maven.artifact.resolver.ArtifactCollector org.apache.maven.artifact.resolver.DefaultArtifactCollector ================================================ FILE: src/test/projects/test-project/src/test/java/org/apache/maven/plugins/shade/AppTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.maven.plugins.shade; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertTrue; /** * Unit test for simple App. */ public class AppTest { /** * Create the test case * * @param testName name of the test case */ /** * Rigourous Test :-) */ @Test public void testApp() { assertTrue(true); } } ================================================ FILE: src/test/resources/components-1.xml ================================================ org.apache.maven.wagon.Wagon http org.apache.maven.wagon.providers.http.LightweightHttpWagon per-lookup LightweightHttpWagon false org.apache.maven.wagon.Wagon https org.apache.maven.wagon.providers.http.LightweightHttpsWagon per-lookup LIghtweightHttpsWagon false User-Agent Apache Maven/${project.version} ================================================ FILE: src/test/resources/components-2.xml ================================================ org.apache.maven.wagon.Wagon http org.apache.maven.wagon.providers.http.LightweightHttpWagon per-lookup LightweightHttpWagon false User-Agent Apache Maven/${project.version} org.apache.maven.wagon.Wagon https org.apache.maven.wagon.providers.http.LightweightHttpsWagon per-lookup LIghtweightHttpsWagon false ================================================ FILE: src/test/resources/components-expected.xml ================================================ org.apache.maven.wagon.Wagon http org.apache.maven.wagon.providers.http.LightweightHttpWagon per-lookup LightweightHttpWagon false User-Agent Apache Maven/${project.version} org.apache.maven.wagon.Wagon https org.apache.maven.wagon.providers.http.LightweightHttpsWagon per-lookup LIghtweightHttpsWagon false User-Agent Apache Maven/${project.version}