diff --git a/.asf.yaml b/.asf.yaml new file mode 100644 index 00000000..0f0ff737 --- /dev/null +++ b/.asf.yaml @@ -0,0 +1,37 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 JAR Plugin" + homepage: https://maven.apache.org/plugins/maven-jar-plugin/ + labels: + - java + - build-management + - maven-plugins + - maven-jar-plugin + - maven + enabled_merge_buttons: + squash: true + merge: false + rebase: true + autolink_jira: + - MJAR +notifications: + commits: commits@maven.apache.org + issues: issues@maven.apache.org + pullrequests: issues@maven.apache.org + jira_options: link label comment diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..d7c9cd4e --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,30 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT 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: 2 +updates: + - package-ecosystem: "maven" + directory: "/" + schedule: + interval: "daily" + ignore: + # Ignore Maven Core updates + - dependency-name: "org.apache.maven:*" + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000..c94da7b5 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,29 @@ +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/MJAR) 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 `[MJAR-XXX] - Fixes bug in ApproximateQuantiles`, + where you replace `MJAR-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). + diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml new file mode 100644 index 00000000..4d504afc --- /dev/null +++ b/.github/release-drafter.yml @@ -0,0 +1,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. + +_extends: maven-gh-actions-shared +tag-template: maven-jar-plugin-$NEXT_MINOR_VERSION diff --git a/.github/workflows/maven-verify.yml b/.github/workflows/maven-verify.yml new file mode 100644 index 00000000..065619be --- /dev/null +++ b/.github/workflows/maven-verify.yml @@ -0,0 +1,30 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT 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 + with: + maven4-enabled: true + diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml new file mode 100644 index 00000000..5205f96e --- /dev/null +++ b/.github/workflows/release-drafter.yml @@ -0,0 +1,28 @@ + + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT 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 diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..2a505ba2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +target/ +.project +.classpath +.settings/ +.svn/ +bin/ +# Intellij +*.ipr +*.iml +.idea +out/ +.DS_Store +/bootstrap +/dependencies.xml +.java-version +.checkstyle +/.factorypath diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 00000000..e9f05f7d --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,20 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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() diff --git a/README.md b/README.md new file mode 100644 index 00000000..81fe13d4 --- /dev/null +++ b/README.md @@ -0,0 +1,100 @@ + +Contributing to [Apache Maven JAR Plugin](https://maven.apache.org/plugins/maven-jar-plugin/) +====================== + +[![ASF Jira](https://img.shields.io/endpoint?url=https%3A%2F%2Fmaven.apache.org%2Fbadges%2Fasf_jira-MJAR.json)][jira] +[![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-jar-plugin.svg?label=Maven%20Central)](https://search.maven.org/artifact/org.apache.maven.plugins/maven-jar-plugin) +[![Reproducible Builds](https://img.shields.io/badge/Reproducible_Builds-ok-green?labelColor=blue)](https://github.com/jvm-repo-rebuild/reproducible-central/blob/master/content/org/apache/maven/plugins/maven-jar-plugin/README.md) +[![Jenkins Status](https://img.shields.io/jenkins/s/https/ci-maven.apache.org/job/Maven/job/maven-box/job/maven-jar-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-jar-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 [JIRA account](https://issues.apache.org/jira/). ++ 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 your commit messages are in the proper format. Your commit message should contain the key of the JIRA issue. +``` +[MJAR-XXX] - Subject of the JIRA Ticket + Optional supplemental description. +``` ++ 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. ++ Update your JIRA ticket and include a link to the pull request in the ticket. + +If you plan to contribute on a regular basis, please consider filing a [contributor license agreement][cla]. + +Making Trivial Changes +---------------------- + +For changes of a trivial nature to comments and documentation, it is not always +necessary to create a new ticket in JIRA. In this case, it is appropriate to +start the first line of a commit with '(doc)' instead of a ticket number. + +Additional Resources +-------------------- + ++ [Contributing patches](https://maven.apache.org/guides/development/guide-maven-development.html#Creating_and_submitting_a_patch) ++ [Apache Maven JAR Plugin JIRA project page][jira] ++ [Contributor License Agreement][cla] ++ [General GitHub documentation](https://help.github.com/) ++ [GitHub pull request documentation](https://help.github.com/send-pull-requests/) ++ [Apache Maven Twitter Account](https://twitter.com/ASFMavenProject) ++ #Maven IRC channel on freenode.org + +[jira]: https://issues.apache.org/jira/projects/MJAR/ +[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-jar-plugin/job/master/lastCompletedBuild/testReport/ +[build]: https://ci-maven.apache.org/job/Maven/job/maven-box/job/maven-jar-plugin/job/master/ diff --git a/pom.xml b/pom.xml index 10bf7d6f..910e227d 100644 --- a/pom.xml +++ b/pom.xml @@ -1,36 +1,34 @@ - - + - 4.0.0 - maven-plugins org.apache.maven.plugins - 30 - ../../pom/maven/maven-plugins/pom.xml + maven-plugins + 42 + maven-jar-plugin - 3.0.2 + 3.4.2 maven-plugin Apache Maven JAR Plugin @@ -42,10 +40,10 @@ under the License. jerome@coffeebreaks.org CoffeeBreaks http://www.coffeebreaks.org - +1 Java Developer + +1 @@ -54,79 +52,129 @@ under the License. - scm:svn:http://svn.apache.org/repos/asf/maven/plugins/tags/maven-jar-plugin-3.0.2 - scm:svn:https://svn.apache.org/repos/asf/maven/plugins/tags/maven-jar-plugin-3.0.2 - http://svn.apache.org/viewvc/maven/plugins/tags/maven-jar-plugin-3.0.2 + scm:git:https://gitbox.apache.org/repos/asf/maven-jar-plugin.git + scm:git:https://gitbox.apache.org/repos/asf/maven-jar-plugin.git + maven-jar-plugin-3.4.2 + https://github.com/apache/maven-jar-plugin/tree/${project.scm.tag} JIRA https://issues.apache.org/jira/browse/MJAR + + Jenkins + https://ci-maven.apache.org/job/Maven/job/maven-box/job/maven-jar-plugin/ + apache.website - scm:svn:https://svn.apache.org/repos/infra/websites/production/maven/components/${maven.site.path} + scm:svn:https://svn.apache.org/repos/asf/maven/website/components/${maven.site.path} - 3.1.1 - 3.0 + 8 + 3.6.3 + 3.6.2 + 2024-06-16T12:09:37Z + + + + commons-io + commons-io + 2.16.1 + + + + + org.apache.maven maven-plugin-api ${mavenVersion} + provided org.apache.maven maven-core ${mavenVersion} + provided org.apache.maven maven-artifact ${mavenVersion} + provided - - org.apache.maven - maven-archiver - ${mavenArchiverVersion} - - + + org.apache.maven.plugin-tools maven-plugin-annotations provided + + + + org.apache.maven.shared + file-management + 3.1.0 + + + org.apache.maven + maven-archiver + ${mavenArchiverVersion} + + + org.codehaus.plexus plexus-archiver - 3.4 + 4.9.2 + + - org.codehaus.plexus - plexus-utils - 3.0.24 + javax.inject + javax.inject + 1 - junit - junit - 4.11 - test + org.slf4j + slf4j-api + 1.7.36 + + - org.apache.maven - maven-compat - ${mavenVersion} + org.junit.jupiter + junit-jupiter-api test org.apache.maven.plugin-testing maven-plugin-testing-harness - 2.1 + 4.0.0-alpha-2 + test + + + org.mockito + mockito-core + 4.11.0 + test + + + org.mockito + mockito-junit-jupiter + 4.11.0 + test + + + org.codehaus.plexus + plexus-xml test @@ -134,8 +182,8 @@ under the License. - src/main/filtered-resources true + src/main/filtered-resources @@ -155,6 +203,13 @@ under the License. + + + + org.eclipse.sisu + sisu-maven-plugin + + @@ -170,6 +225,7 @@ under the License. clean package + true diff --git a/src/it/MJAR-162/pom.xml b/src/it/MJAR-162/pom.xml index 63c48325..cd268163 100644 --- a/src/it/MJAR-162/pom.xml +++ b/src/it/MJAR-162/pom.xml @@ -32,12 +32,17 @@ junit junit - 3.8.1 + 4.13.2 test + + org.apache.maven.plugins + maven-resources-plugin + 3.3.0 + org.apache.maven.plugins maven-jar-plugin diff --git a/src/it/MJAR-162/verify.bsh b/src/it/MJAR-162/verify.bsh index d339c673..d4f0f82f 100644 --- a/src/it/MJAR-162/verify.bsh +++ b/src/it/MJAR-162/verify.bsh @@ -21,7 +21,6 @@ import java.io.*; import java.util.*; import java.util.jar.*; -import org.codehaus.plexus.util.*; boolean result = true; diff --git a/src/it/MJAR-183/verify.bsh b/src/it/MJAR-183/verify.bsh index a9aeea50..a024918f 100644 --- a/src/it/MJAR-183/verify.bsh +++ b/src/it/MJAR-183/verify.bsh @@ -21,7 +21,6 @@ import java.io.*; import java.util.*; import java.util.jar.*; -import org.codehaus.plexus.util.*; boolean result = true; diff --git a/src/it/MJAR-199-change-classifier/verify.bsh b/src/it/MJAR-199-change-classifier/verify.bsh index 2f82c46d..27dc60cc 100644 --- a/src/it/MJAR-199-change-classifier/verify.bsh +++ b/src/it/MJAR-199-change-classifier/verify.bsh @@ -21,7 +21,6 @@ import java.io.*; import java.util.*; import java.util.jar.*; -import org.codehaus.plexus.util.*; boolean result = true; diff --git a/src/it/MJAR-199/verify.bsh b/src/it/MJAR-199/verify.bsh index 18c8b254..e788c149 100644 --- a/src/it/MJAR-199/verify.bsh +++ b/src/it/MJAR-199/verify.bsh @@ -21,7 +21,6 @@ import java.io.*; import java.util.*; import java.util.jar.*; -import org.codehaus.plexus.util.*; boolean result = true; diff --git a/src/it/MJAR-228/pom.xml b/src/it/MJAR-228/pom.xml index fbba5b66..4508032e 100644 --- a/src/it/MJAR-228/pom.xml +++ b/src/it/MJAR-228/pom.xml @@ -31,7 +31,7 @@ junit junit - 4.11 + 4.13.2 diff --git a/src/it/MJAR-228/verify.bsh b/src/it/MJAR-228/verify.bsh index 09eb0a2a..9fe1b9c9 100644 --- a/src/it/MJAR-228/verify.bsh +++ b/src/it/MJAR-228/verify.bsh @@ -21,7 +21,6 @@ import java.io.*; import java.util.*; import java.util.jar.*; -import org.codehaus.plexus.util.*; boolean result = true; @@ -45,21 +44,15 @@ try Attributes manifest = jar.getManifest().getMainAttributes(); - if ( !manifest.getValue( new Attributes.Name( "Created-By" ) ).startsWith( "Apache Maven" ) ) - { - System.err.println( "Created-By not equals Apache Maven" ); - return false; - } - if ( !"myproject.HelloWorld".equals( manifest.get( Attributes.Name.MAIN_CLASS ) ) ) { System.err.println( Attributes.Name.MAIN_CLASS.toString() + " not equals myproject.HelloWorld" ); return false; } - if ( !"lib/junit-4.11.jar lib/hamcrest-core-1.3.jar".equals( manifest.get( Attributes.Name.CLASS_PATH ) ) ) + if ( !"lib/junit-4.13.2.jar lib/hamcrest-core-1.3.jar".equals( manifest.get( Attributes.Name.CLASS_PATH ) ) ) { System.err.println( Attributes.Name.CLASS_PATH.toString() + - " not equals lib/junit-4.11.jar lib/hamcrest-core-1.3.jar" ); + " not equals lib/junit-4.13.2.jar lib/hamcrest-core-1.3.jar" ); return false; } diff --git a/src/it/MJAR-238-modular-jar-main-class/invoker.properties b/src/it/MJAR-238-modular-jar-main-class/invoker.properties new file mode 100644 index 00000000..95117185 --- /dev/null +++ b/src/it/MJAR-238-modular-jar-main-class/invoker.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +invoker.java.version = 9+ diff --git a/src/it/MJAR-238-modular-jar-main-class/pom.xml b/src/it/MJAR-238-modular-jar-main-class/pom.xml new file mode 100644 index 00000000..ebb31f6b --- /dev/null +++ b/src/it/MJAR-238-modular-jar-main-class/pom.xml @@ -0,0 +1,57 @@ + + + + 4.0.0 + org.apache.maven.plugins + mjar-238-modular-jar-main-class + mjar-238-modular-jar-main-class + Verifies that the modular descriptor main class is set for modular Jar files + jar + 1.0-SNAPSHOT + + + + + org.apache.maven.plugins + maven-jar-plugin + @project.version@ + + + + myproject.HelloWorld + + + + + + + + + + maven-compiler-plugin + + 1.9 + 1.9 + + + + + + diff --git a/src/it/MJAR-238-modular-jar-main-class/src/main/java/module-info.java b/src/it/MJAR-238-modular-jar-main-class/src/main/java/module-info.java new file mode 100644 index 00000000..fa450345 --- /dev/null +++ b/src/it/MJAR-238-modular-jar-main-class/src/main/java/module-info.java @@ -0,0 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +module myproject { + exports myproject; +} diff --git a/src/it/MJAR-238-modular-jar-main-class/src/main/java/myproject/HelloWorld.java b/src/it/MJAR-238-modular-jar-main-class/src/main/java/myproject/HelloWorld.java new file mode 100644 index 00000000..fd0ad83c --- /dev/null +++ b/src/it/MJAR-238-modular-jar-main-class/src/main/java/myproject/HelloWorld.java @@ -0,0 +1,36 @@ +package myproject; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * The classic Hello World App. + */ +public class HelloWorld { + + /** + * Main method. + * + * @param args Not used + */ + public static void main( String[] args ) + { + System.out.println( "Hi!" ); + } +} \ No newline at end of file diff --git a/src/it/MJAR-238-modular-jar-main-class/verify.bsh b/src/it/MJAR-238-modular-jar-main-class/verify.bsh new file mode 100644 index 00000000..7774fe23 --- /dev/null +++ b/src/it/MJAR-238-modular-jar-main-class/verify.bsh @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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.lang.module.*; +import java.util.jar.*; + +boolean result = true; +JarFile jar; + +try +{ + File target = new File( basedir, "target" ); + if ( !target.exists() || !target.isDirectory() ) + { + System.err.println( "target file is missing or not a directory." ); + return false; + } + + File artifact = new File( target, "mjar-238-modular-jar-main-class-1.0-SNAPSHOT.jar" ); + if ( !artifact.exists() || artifact.isDirectory() ) + { + System.err.println( "artifact file is missing or a directory." ); + return false; + } + + jar = new JarFile( artifact ); + + Attributes manifest = jar.getManifest().getMainAttributes(); + + if ( !"myproject.HelloWorld".equals( manifest.get( Attributes.Name.MAIN_CLASS ) ) ) + { + System.err.println( "Manifest main class attribute not equals myproject.HelloWorld" ); + return false; + } + + InputStream moduleDescriptorInputStream = jar.getInputStream( jar.getEntry( "module-info.class" ) ); + ModuleDescriptor moduleDescriptor = ModuleDescriptor.read( moduleDescriptorInputStream ); + + if ( !"myproject.HelloWorld".equals( moduleDescriptor.mainClass().orElse( null ) ) ) + { + System.err.println( "Module descriptor main class not equals myproject.HelloWorld" ); + return false; + } +} +catch( Throwable e ) +{ + e.printStackTrace(); + result = false; +} +finally +{ + if ( jar != null ) + { + jar.close(); + } +} + +return result; diff --git a/src/it/MJAR-260-invalid-automatic-module-name/invoker.properties b/src/it/MJAR-260-invalid-automatic-module-name/invoker.properties new file mode 100644 index 00000000..4789d911 --- /dev/null +++ b/src/it/MJAR-260-invalid-automatic-module-name/invoker.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +invoker.buildResult=failure diff --git a/src/it/MJAR-260-invalid-automatic-module-name/pom.xml b/src/it/MJAR-260-invalid-automatic-module-name/pom.xml new file mode 100644 index 00000000..4046808a --- /dev/null +++ b/src/it/MJAR-260-invalid-automatic-module-name/pom.xml @@ -0,0 +1,46 @@ + + + + 4.0.0 + org.apache.maven.plugins + mjar260-invalid-automatic-module-name + MJAR-260-invalid-automatic-module-name + jar + 1.0-SNAPSHOT + + jar plugin it + + + + + org.apache.maven.plugins + maven-jar-plugin + @project.version@ + + + + in-valid.name.with.new.keyword + + + + + + + diff --git a/src/it/MJAR-260-invalid-automatic-module-name/src/main/java/myproject/HelloWorld.java b/src/it/MJAR-260-invalid-automatic-module-name/src/main/java/myproject/HelloWorld.java new file mode 100644 index 00000000..fd0ad83c --- /dev/null +++ b/src/it/MJAR-260-invalid-automatic-module-name/src/main/java/myproject/HelloWorld.java @@ -0,0 +1,36 @@ +package myproject; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * The classic Hello World App. + */ +public class HelloWorld { + + /** + * Main method. + * + * @param args Not used + */ + public static void main( String[] args ) + { + System.out.println( "Hi!" ); + } +} \ No newline at end of file diff --git a/src/it/MJAR-260-invalid-automatic-module-name/verify.bsh b/src/it/MJAR-260-invalid-automatic-module-name/verify.bsh new file mode 100644 index 00000000..32538953 --- /dev/null +++ b/src/it/MJAR-260-invalid-automatic-module-name/verify.bsh @@ -0,0 +1,68 @@ + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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.nio.file.*; +import java.util.*; +import java.util.jar.*; + +boolean result = true; + +try +{ + File target = new File( basedir, "target" ); + if ( !target.exists() || !target.isDirectory() ) + { + System.err.println( "target file is missing or not a directory." ); + return false; + } + + File artifact = new File( target, "mjar260-invalid-automatic-module-name-1.0-SNAPSHOT.jar" ); + if ( artifact.exists() || artifact.isDirectory() ) + { + System.err.println( "artifact file is created or a directory." ); + return false; + } + + String log = new String(Files.readAllBytes(basedir.toPath().resolve("build.log")), "UTF-8"); + String[] snippets = new String[] { + "[INFO] BUILD FAILURE", + "[ERROR] Failed to execute goal org.apache.maven.plugins:maven-jar-plugin", + "Caused by: org.apache.maven.plugin.MojoExecutionException: Error assembling JAR", + "Caused by: org.codehaus.plexus.archiver.jar.ManifestException: Invalid automatic module name: 'in-valid.name.with.new.keyword'" + }; + + System.out.println("\nVerifying log snippets..."); + for (String snippet : snippets) { + if (!log.contains(snippet)) { + System.err.println("XXX| Snippet `" + snippet + "` not found"); + result = false; + continue; + } + System.out.println(" | `" + snippet + "` found in log"); + } +} +catch( Throwable e ) +{ + e.printStackTrace(); + result = false; +} + +return result; diff --git a/src/it/MJAR-260-valid-automatic-module-name/pom.xml b/src/it/MJAR-260-valid-automatic-module-name/pom.xml new file mode 100644 index 00000000..ede7f616 --- /dev/null +++ b/src/it/MJAR-260-valid-automatic-module-name/pom.xml @@ -0,0 +1,46 @@ + + + + 4.0.0 + org.apache.maven.plugins + mjar260-valid-automatic-module-name + MJAR-260-valid-automatic-module-name + jar + 1.0-SNAPSHOT + + jar plugin it + + + + + org.apache.maven.plugins + maven-jar-plugin + @project.version@ + + + + valid.automatic.module.name + + + + + + + diff --git a/src/it/MJAR-260-valid-automatic-module-name/src/main/java/myproject/HelloWorld.java b/src/it/MJAR-260-valid-automatic-module-name/src/main/java/myproject/HelloWorld.java new file mode 100644 index 00000000..fd0ad83c --- /dev/null +++ b/src/it/MJAR-260-valid-automatic-module-name/src/main/java/myproject/HelloWorld.java @@ -0,0 +1,36 @@ +package myproject; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * The classic Hello World App. + */ +public class HelloWorld { + + /** + * Main method. + * + * @param args Not used + */ + public static void main( String[] args ) + { + System.out.println( "Hi!" ); + } +} \ No newline at end of file diff --git a/src/it/MJAR-260-valid-automatic-module-name/verify.bsh b/src/it/MJAR-260-valid-automatic-module-name/verify.bsh new file mode 100644 index 00000000..0618e581 --- /dev/null +++ b/src/it/MJAR-260-valid-automatic-module-name/verify.bsh @@ -0,0 +1,51 @@ + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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.jar.*; + +boolean result = true; + +try +{ + File target = new File( basedir, "target" ); + if ( !target.exists() || !target.isDirectory() ) + { + System.err.println( "target file is missing or not a directory." ); + return false; + } + + File artifact = new File( target, "mjar260-valid-automatic-module-name-1.0-SNAPSHOT.jar" ); + if ( !artifact.exists() || artifact.isDirectory() ) + { + System.err.println( "artifact file is missing or a directory." ); + return false; + } + + +} +catch( Throwable e ) +{ + e.printStackTrace(); + result = false; +} + +return result; diff --git a/src/it/MJAR-275-reproducible-module-info/invoker.properties b/src/it/MJAR-275-reproducible-module-info/invoker.properties new file mode 100644 index 00000000..71eea457 --- /dev/null +++ b/src/it/MJAR-275-reproducible-module-info/invoker.properties @@ -0,0 +1,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. + +# NOTE: Requires Java 10+ to compile the module declaration for Java 9+, +# this is due that compiling the module declaration generates a +# module descriptor with the JDK version on it, making it unreproducible. +invoker.java.version = 10+ diff --git a/src/it/MJAR-275-reproducible-module-info/pom.xml b/src/it/MJAR-275-reproducible-module-info/pom.xml new file mode 100644 index 00000000..c25061c5 --- /dev/null +++ b/src/it/MJAR-275-reproducible-module-info/pom.xml @@ -0,0 +1,77 @@ + + + + 4.0.0 + org.apache.maven.plugins + mjar-275-reproducible-multi-release-modular-jar + mjar-275-reproducible-multi-release-modular-jar + Verifies that the modular descriptor is reproducible (timestamp is set) + jar + 1.0-SNAPSHOT + + + UTF-8 + 2022-06-26T13:25:58Z + + + + + + org.apache.maven.plugins + maven-jar-plugin + @project.version@ + + + + myproject.HelloWorld + + + + + + + + + + maven-compiler-plugin + 3.10.1 + + 8 + + + + java9 + + compile + + + 9 + + ${project.basedir}/src/main/java9 + + true + + + + + + + + diff --git a/src/it/MJAR-275-reproducible-module-info/src/main/java/myproject/HelloWorld.java b/src/it/MJAR-275-reproducible-module-info/src/main/java/myproject/HelloWorld.java new file mode 100644 index 00000000..01f29914 --- /dev/null +++ b/src/it/MJAR-275-reproducible-module-info/src/main/java/myproject/HelloWorld.java @@ -0,0 +1,37 @@ +package myproject; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * The classic Hello World App. + */ +public class HelloWorld +{ + + /** + * Main method. + * + * @param args Not used + */ + public static void main( String[] args ) + { + System.out.println( "Hi!" ); + } +} \ No newline at end of file diff --git a/src/it/MJAR-275-reproducible-module-info/src/main/java9/module-info.java b/src/it/MJAR-275-reproducible-module-info/src/main/java9/module-info.java new file mode 100644 index 00000000..fa450345 --- /dev/null +++ b/src/it/MJAR-275-reproducible-module-info/src/main/java9/module-info.java @@ -0,0 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +module myproject { + exports myproject; +} diff --git a/src/it/MJAR-275-reproducible-module-info/verify.groovy b/src/it/MJAR-275-reproducible-module-info/verify.groovy new file mode 100644 index 00000000..f6bce523 --- /dev/null +++ b/src/it/MJAR-275-reproducible-module-info/verify.groovy @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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.lang.module.*; +import java.nio.file.attribute.FileTime; +import java.time.Instant; +import java.util.*; +import java.util.jar.*; + +File target = new File( basedir, "target" ) + +assert target.exists() +assert target.isDirectory() + +File artifact = new File( target, "mjar-275-reproducible-multi-release-modular-jar-1.0-SNAPSHOT.jar" ); + +assert artifact.exists() +assert artifact.isFile() + +JarFile jar = new JarFile( artifact ); + +Attributes manifest = jar.getManifest().getMainAttributes(); + +assert "myproject.HelloWorld".equals( manifest.get( Attributes.Name.MAIN_CLASS ) ) + +InputStream moduleDescriptorInputStream = jar.getInputStream( jar.getEntry( "META-INF/versions/9/module-info.class" ) ); +ModuleDescriptor moduleDescriptor = ModuleDescriptor.read( moduleDescriptorInputStream ); + +assert "myproject.HelloWorld".equals( moduleDescriptor.mainClass().orElse( null ) ) + +// Normalize to UTC +long normalizeUTC( String timestamp ) +{ + long millis = Instant.parse( timestamp ).toEpochMilli(); + Calendar cal = Calendar.getInstance(); + cal.setTimeInMillis( millis ); + return millis - ( cal.get( Calendar.ZONE_OFFSET ) + cal.get( Calendar.DST_OFFSET ) ); +} + +// All entries should have the same timestamp +FileTime expectedTimestamp = FileTime.fromMillis( normalizeUTC( "2022-06-26T13:25:58Z" ) ); +Enumeration entries = jar.entries(); +while ( entries.hasMoreElements() ) +{ + assert expectedTimestamp.equals( entries.nextElement().getLastModifiedTime() ) +} + +jar.close(); diff --git a/src/it/MJAR-292-detect-mjar-no-versions/invoker.properties b/src/it/MJAR-292-detect-mjar-no-versions/invoker.properties new file mode 100644 index 00000000..d41b77b4 --- /dev/null +++ b/src/it/MJAR-292-detect-mjar-no-versions/invoker.properties @@ -0,0 +1,20 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT 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 = 10+ + +invoker.name = MJAR-292 Missing versions for MRJAR +invoker.description = Checks the Multi-Release attribute is missing \ No newline at end of file diff --git a/src/it/MJAR-292-detect-mjar-no-versions/pom.xml b/src/it/MJAR-292-detect-mjar-no-versions/pom.xml new file mode 100644 index 00000000..7a82a2d9 --- /dev/null +++ b/src/it/MJAR-292-detect-mjar-no-versions/pom.xml @@ -0,0 +1,93 @@ + + + + 4.0.0 + + org.apache.maven.plugins + mjar-292-detect-multi-release-jar + mjar-292-detect-multi-release-jar + Verifies that the multi-release jar contains the manifest entry + jar + 1.0-SNAPSHOT + + + UTF-8 + 2022-12-22T13:25:58Z + + + + + + org.apache.maven.plugins + maven-jar-plugin + @project.version@ + + + + myproject.HelloWorld + + + + + + + + + + maven-compiler-plugin + 3.10.1 + + 8 + + + + java9 + + compile + + + 9 + + ${project.basedir}/src/main/java9 + + true + + + + java10 + + compile + + + 10 + + ${project.basedir}/src/main/java10 + + true + + + + + + + + diff --git a/src/it/MJAR-292-detect-mjar-no-versions/src/main/java/myproject/HelloWorld.java b/src/it/MJAR-292-detect-mjar-no-versions/src/main/java/myproject/HelloWorld.java new file mode 100644 index 00000000..85a84d82 --- /dev/null +++ b/src/it/MJAR-292-detect-mjar-no-versions/src/main/java/myproject/HelloWorld.java @@ -0,0 +1,37 @@ +package myproject; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * The classic Hello World App. + */ +public class HelloWorld +{ + + /** + * Main method. + * + * @param args Not used + */ + public static void main( String[] args ) + { + System.out.println( new Utils().getJavaVersion() ); + } +} \ No newline at end of file diff --git a/src/it/MJAR-292-detect-mjar-no-versions/src/main/java/myproject/Utils.java b/src/it/MJAR-292-detect-mjar-no-versions/src/main/java/myproject/Utils.java new file mode 100644 index 00000000..eea2683a --- /dev/null +++ b/src/it/MJAR-292-detect-mjar-no-versions/src/main/java/myproject/Utils.java @@ -0,0 +1,32 @@ +package myproject; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * The classic Utils class. + */ +public class Utils +{ + public String getJavaVersion() + { + System.out.println("Running Java 8 (base) version"); + return System.getProperty( "java.specification.version" ); + } +} diff --git a/src/it/MJAR-292-detect-mjar-no-versions/verify.groovy b/src/it/MJAR-292-detect-mjar-no-versions/verify.groovy new file mode 100644 index 00000000..8578151b --- /dev/null +++ b/src/it/MJAR-292-detect-mjar-no-versions/verify.groovy @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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.*; + +def mrjar = new JarFile(new File(basedir,'target/mjar-292-detect-multi-release-jar-1.0-SNAPSHOT.jar')) +def manifest = mrjar.manifest.mainAttributes + +assert manifest.getValue( Attributes.Name.MAIN_CLASS ) == "myproject.HelloWorld" +assert manifest.getValue( Attributes.Name.MULTI_RELEASE ) == null diff --git a/src/it/MJAR-292-detect-mjar/invoker.properties b/src/it/MJAR-292-detect-mjar/invoker.properties new file mode 100644 index 00000000..dbd7d90c --- /dev/null +++ b/src/it/MJAR-292-detect-mjar/invoker.properties @@ -0,0 +1,20 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT 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 = 10+ + +invoker.name = MJAR-292 Detect MRJAR +invoker.description = Checks the Multi-Release attribute is true \ No newline at end of file diff --git a/src/it/MJAR-292-detect-mjar/pom.xml b/src/it/MJAR-292-detect-mjar/pom.xml new file mode 100644 index 00000000..f3e1165d --- /dev/null +++ b/src/it/MJAR-292-detect-mjar/pom.xml @@ -0,0 +1,101 @@ + + + + 4.0.0 + + org.apache.maven.plugins + mjar-292-detect-multi-release-jar + mjar-292-detect-multi-release-jar + Verifies that the multi-release jar contains the manifest entry + jar + 1.0-SNAPSHOT + + + UTF-8 + 2022-12-22T13:25:58Z + + + + + + org.apache.maven.plugins + maven-jar-plugin + @project.version@ + + + + myproject.HelloWorld + true + + + + false + + + + + + + + + + maven-compiler-plugin + 3.10.1 + + 8 + + + + java9 + + compile + + + 9 + + ${project.basedir}/src/main/java9 + + true + + + + java10 + + compile + + + 10 + + ${project.basedir}/src/main/java10 + + true + + + + + + + + diff --git a/src/it/MJAR-292-detect-mjar/src/main/java/myproject/HelloWorld.java b/src/it/MJAR-292-detect-mjar/src/main/java/myproject/HelloWorld.java new file mode 100644 index 00000000..85a84d82 --- /dev/null +++ b/src/it/MJAR-292-detect-mjar/src/main/java/myproject/HelloWorld.java @@ -0,0 +1,37 @@ +package myproject; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * The classic Hello World App. + */ +public class HelloWorld +{ + + /** + * Main method. + * + * @param args Not used + */ + public static void main( String[] args ) + { + System.out.println( new Utils().getJavaVersion() ); + } +} \ No newline at end of file diff --git a/src/it/MJAR-292-detect-mjar/src/main/java/myproject/Utils.java b/src/it/MJAR-292-detect-mjar/src/main/java/myproject/Utils.java new file mode 100644 index 00000000..eea2683a --- /dev/null +++ b/src/it/MJAR-292-detect-mjar/src/main/java/myproject/Utils.java @@ -0,0 +1,32 @@ +package myproject; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * The classic Utils class. + */ +public class Utils +{ + public String getJavaVersion() + { + System.out.println("Running Java 8 (base) version"); + return System.getProperty( "java.specification.version" ); + } +} diff --git a/src/it/MJAR-292-detect-mjar/src/main/java10/myproject/Utils.java b/src/it/MJAR-292-detect-mjar/src/main/java10/myproject/Utils.java new file mode 100644 index 00000000..b0bf5c78 --- /dev/null +++ b/src/it/MJAR-292-detect-mjar/src/main/java10/myproject/Utils.java @@ -0,0 +1,33 @@ +package myproject; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * The classic Utils class. + */ +public class Utils +{ + public String getJavaVersion() + { + System.out.println("Running Java 10+ version"); + Runtime.Version runtimeVersion = Runtime.version(); + return String.valueOf( runtimeVersion.feature() ); + } +} diff --git a/src/it/MJAR-292-detect-mjar/src/main/java9/myproject/Utils.java b/src/it/MJAR-292-detect-mjar/src/main/java9/myproject/Utils.java new file mode 100644 index 00000000..613f10cc --- /dev/null +++ b/src/it/MJAR-292-detect-mjar/src/main/java9/myproject/Utils.java @@ -0,0 +1,33 @@ +package myproject; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * The classic Utils class. + */ +public class Utils +{ + public String getJavaVersion() + { + System.out.println( "Running Java 9 version" ); + Runtime.Version runtimeVersion = Runtime.version(); + return String.valueOf( runtimeVersion.major() ); + } +} diff --git a/src/it/MJAR-292-detect-mjar/verify.groovy b/src/it/MJAR-292-detect-mjar/verify.groovy new file mode 100644 index 00000000..a06ef63d --- /dev/null +++ b/src/it/MJAR-292-detect-mjar/verify.groovy @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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.*; + +def mrjar = new JarFile(new File(basedir,'target/mjar-292-detect-multi-release-jar-1.0-SNAPSHOT.jar')) +def manifest = mrjar.manifest.mainAttributes + +assert manifest.getValue( Attributes.Name.MAIN_CLASS ) == "myproject.HelloWorld" +assert manifest.getValue( Attributes.Name.MULTI_RELEASE ) == "true" diff --git a/src/it/MJAR-292-disable-detect-mjar/invoker.properties b/src/it/MJAR-292-disable-detect-mjar/invoker.properties new file mode 100644 index 00000000..034f5aa8 --- /dev/null +++ b/src/it/MJAR-292-disable-detect-mjar/invoker.properties @@ -0,0 +1,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. +invoker.java.version = 10+ +invoker.goals = clean package -Dmaven.jar.detectMultiReleaseJar=false + +invoker.name = MJAR-292 MRJAR detection disabled +invoker.description = Checks the Multi-Release attribute is not set \ No newline at end of file diff --git a/src/it/MJAR-292-disable-detect-mjar/pom.xml b/src/it/MJAR-292-disable-detect-mjar/pom.xml new file mode 100644 index 00000000..7a82a2d9 --- /dev/null +++ b/src/it/MJAR-292-disable-detect-mjar/pom.xml @@ -0,0 +1,93 @@ + + + + 4.0.0 + + org.apache.maven.plugins + mjar-292-detect-multi-release-jar + mjar-292-detect-multi-release-jar + Verifies that the multi-release jar contains the manifest entry + jar + 1.0-SNAPSHOT + + + UTF-8 + 2022-12-22T13:25:58Z + + + + + + org.apache.maven.plugins + maven-jar-plugin + @project.version@ + + + + myproject.HelloWorld + + + + + + + + + + maven-compiler-plugin + 3.10.1 + + 8 + + + + java9 + + compile + + + 9 + + ${project.basedir}/src/main/java9 + + true + + + + java10 + + compile + + + 10 + + ${project.basedir}/src/main/java10 + + true + + + + + + + + diff --git a/src/it/MJAR-292-disable-detect-mjar/src/main/java/myproject/HelloWorld.java b/src/it/MJAR-292-disable-detect-mjar/src/main/java/myproject/HelloWorld.java new file mode 100644 index 00000000..85a84d82 --- /dev/null +++ b/src/it/MJAR-292-disable-detect-mjar/src/main/java/myproject/HelloWorld.java @@ -0,0 +1,37 @@ +package myproject; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * The classic Hello World App. + */ +public class HelloWorld +{ + + /** + * Main method. + * + * @param args Not used + */ + public static void main( String[] args ) + { + System.out.println( new Utils().getJavaVersion() ); + } +} \ No newline at end of file diff --git a/src/it/MJAR-292-disable-detect-mjar/src/main/java/myproject/Utils.java b/src/it/MJAR-292-disable-detect-mjar/src/main/java/myproject/Utils.java new file mode 100644 index 00000000..eea2683a --- /dev/null +++ b/src/it/MJAR-292-disable-detect-mjar/src/main/java/myproject/Utils.java @@ -0,0 +1,32 @@ +package myproject; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * The classic Utils class. + */ +public class Utils +{ + public String getJavaVersion() + { + System.out.println("Running Java 8 (base) version"); + return System.getProperty( "java.specification.version" ); + } +} diff --git a/src/it/MJAR-292-disable-detect-mjar/src/main/java10/myproject/Utils.java b/src/it/MJAR-292-disable-detect-mjar/src/main/java10/myproject/Utils.java new file mode 100644 index 00000000..b0bf5c78 --- /dev/null +++ b/src/it/MJAR-292-disable-detect-mjar/src/main/java10/myproject/Utils.java @@ -0,0 +1,33 @@ +package myproject; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * The classic Utils class. + */ +public class Utils +{ + public String getJavaVersion() + { + System.out.println("Running Java 10+ version"); + Runtime.Version runtimeVersion = Runtime.version(); + return String.valueOf( runtimeVersion.feature() ); + } +} diff --git a/src/it/MJAR-292-disable-detect-mjar/src/main/java9/myproject/Utils.java b/src/it/MJAR-292-disable-detect-mjar/src/main/java9/myproject/Utils.java new file mode 100644 index 00000000..613f10cc --- /dev/null +++ b/src/it/MJAR-292-disable-detect-mjar/src/main/java9/myproject/Utils.java @@ -0,0 +1,33 @@ +package myproject; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * The classic Utils class. + */ +public class Utils +{ + public String getJavaVersion() + { + System.out.println( "Running Java 9 version" ); + Runtime.Version runtimeVersion = Runtime.version(); + return String.valueOf( runtimeVersion.major() ); + } +} diff --git a/src/it/MJAR-292-disable-detect-mjar/verify.groovy b/src/it/MJAR-292-disable-detect-mjar/verify.groovy new file mode 100644 index 00000000..8578151b --- /dev/null +++ b/src/it/MJAR-292-disable-detect-mjar/verify.groovy @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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.*; + +def mrjar = new JarFile(new File(basedir,'target/mjar-292-detect-multi-release-jar-1.0-SNAPSHOT.jar')) +def manifest = mrjar.manifest.mainAttributes + +assert manifest.getValue( Attributes.Name.MAIN_CLASS ) == "myproject.HelloWorld" +assert manifest.getValue( Attributes.Name.MULTI_RELEASE ) == null diff --git a/src/it/MJAR-296-exclude-default/pom.xml b/src/it/MJAR-296-exclude-default/pom.xml new file mode 100644 index 00000000..1cdf068f --- /dev/null +++ b/src/it/MJAR-296-exclude-default/pom.xml @@ -0,0 +1,58 @@ + + + + 4.0.0 + + org.apache.maven.plugins + mjar-296-exclude-default + mjar-296-suppress-default-excludes + Verifies that the resulting jar not includes files excluded by default + jar + 1.0-SNAPSHOT + + + UTF-8 + 2023-11-19T13:25:58Z + + + + + + + org.apache.maven.plugins + maven-resources-plugin + @version.maven-resources-plugin@ + + false + + + + + + + org.apache.maven.plugins + maven-jar-plugin + @project.version@ + + + + diff --git a/src/it/MJAR-296-exclude-default/setup.groovy b/src/it/MJAR-296-exclude-default/setup.groovy new file mode 100644 index 00000000..ab30042c --- /dev/null +++ b/src/it/MJAR-296-exclude-default/setup.groovy @@ -0,0 +1,29 @@ +import java.nio.file.Files +import java.nio.file.Paths + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +// excluded files are not copied by m-invoker-p - so we need create one + +def resDir = basedir.toPath().resolve("src/main/resources") +Files.createDirectories(resDir) +Files.createFile(resDir.resolve(".cvsignore")) + +return true diff --git a/src/it/MJAR-296-exclude-default/src/main/java/Foo.java b/src/it/MJAR-296-exclude-default/src/main/java/Foo.java new file mode 100644 index 00000000..f939fa6a --- /dev/null +++ b/src/it/MJAR-296-exclude-default/src/main/java/Foo.java @@ -0,0 +1,31 @@ + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Hello world! + * + */ +public class Foo +{ + public static void main( String[] args ) + { + System.out.println( "Hello World!" ); + } +} diff --git a/src/it/MJAR-296-exclude-default/verify.groovy b/src/it/MJAR-296-exclude-default/verify.groovy new file mode 100644 index 00000000..9599b984 --- /dev/null +++ b/src/it/MJAR-296-exclude-default/verify.groovy @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.jar.*; + +def target = new File(basedir, "target") + +def cvsignore = new File(target, "classes/.cvsignore") +assert cvsignore.exists() + +def artifact = new File(target, "mjar-296-exclude-default-1.0-SNAPSHOT.jar") +assert artifact.exists() + +def jar = new JarFile(artifact) +assert ".cvsignore" !in jar.entries()*.name diff --git a/src/it/MJAR-296-suppress-default-excludes/pom.xml b/src/it/MJAR-296-suppress-default-excludes/pom.xml new file mode 100644 index 00000000..9ff5b450 --- /dev/null +++ b/src/it/MJAR-296-suppress-default-excludes/pom.xml @@ -0,0 +1,61 @@ + + + + 4.0.0 + + org.apache.maven.plugins + mjar-296-suppress-default-excludes + mjar-296-suppress-default-excludes + Verifies that the resulting jar includes files excluded by default + jar + 1.0-SNAPSHOT + + + UTF-8 + 2023-11-19T13:25:58Z + + + + + + + org.apache.maven.plugins + maven-resources-plugin + @version.maven-resources-plugin@ + + false + + + + + + + org.apache.maven.plugins + maven-jar-plugin + @project.version@ + + false + + + + + diff --git a/src/it/MJAR-296-suppress-default-excludes/setup.groovy b/src/it/MJAR-296-suppress-default-excludes/setup.groovy new file mode 100644 index 00000000..324bf2bb --- /dev/null +++ b/src/it/MJAR-296-suppress-default-excludes/setup.groovy @@ -0,0 +1,29 @@ +import java.nio.file.Files +import java.nio.file.Path +import java.nio.file.Paths + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +// excluded files are not copied by m-invoker-p - so we need create one +def resDir = basedir.toPath().resolve("src/main/resources") +Files.createDirectories(resDir) +Files.createFile(resDir.resolve(".cvsignore")) + +return true diff --git a/src/it/MJAR-296-suppress-default-excludes/src/main/java/Foo.java b/src/it/MJAR-296-suppress-default-excludes/src/main/java/Foo.java new file mode 100644 index 00000000..f939fa6a --- /dev/null +++ b/src/it/MJAR-296-suppress-default-excludes/src/main/java/Foo.java @@ -0,0 +1,31 @@ + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Hello world! + * + */ +public class Foo +{ + public static void main( String[] args ) + { + System.out.println( "Hello World!" ); + } +} diff --git a/src/it/MJAR-296-suppress-default-excludes/verify.groovy b/src/it/MJAR-296-suppress-default-excludes/verify.groovy new file mode 100644 index 00000000..806c90ef --- /dev/null +++ b/src/it/MJAR-296-suppress-default-excludes/verify.groovy @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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.*; + +def target = new File(basedir, "target") + +def cvsignore = new File(target, "classes/.cvsignore") +assert cvsignore.exists() + +def artifact = new File(target, "mjar-296-suppress-default-excludes-1.0-SNAPSHOT.jar") +assert artifact.exists() + +def jar = new JarFile(artifact) +assert ".cvsignore" in jar.entries()*.name + + diff --git a/src/it/MJAR-30-excludes/verify.bsh b/src/it/MJAR-30-excludes/verify.groovy similarity index 93% rename from src/it/MJAR-30-excludes/verify.bsh rename to src/it/MJAR-30-excludes/verify.groovy index b2a46079..dafd74f2 100644 --- a/src/it/MJAR-30-excludes/verify.bsh +++ b/src/it/MJAR-30-excludes/verify.groovy @@ -21,7 +21,6 @@ import java.io.*; import java.util.*; import java.util.jar.*; -import org.codehaus.plexus.util.*; boolean result = true; @@ -41,9 +40,9 @@ try return false; } - String[] artifactNames = new String[] { "default-configuration.properties", "META-INF/MANIFEST.MF", + String[] artifactNames = [ "default-configuration.properties", "META-INF/MANIFEST.MF", "META-INF/maven/org.apache.maven.plugins/maven-jar-plugin-test-mjar-30-03/pom.properties", - "META-INF/maven/org.apache.maven.plugins/maven-jar-plugin-test-mjar-30-03/pom.xml" }; + "META-INF/maven/org.apache.maven.plugins/maven-jar-plugin-test-mjar-30-03/pom.xml" ]; Set contents = new HashSet(); diff --git a/src/it/MJAR-30-fullcontent/verify.bsh b/src/it/MJAR-30-fullcontent/verify.groovy similarity index 94% rename from src/it/MJAR-30-fullcontent/verify.bsh rename to src/it/MJAR-30-fullcontent/verify.groovy index b8d30160..89ad38d9 100644 --- a/src/it/MJAR-30-fullcontent/verify.bsh +++ b/src/it/MJAR-30-fullcontent/verify.groovy @@ -21,7 +21,6 @@ import java.io.*; import java.util.*; import java.util.jar.*; -import org.codehaus.plexus.util.*; boolean result = true; @@ -41,10 +40,10 @@ try return false; } - String[] artifactNames = new String[] { "default-configuration.properties", + String[] artifactNames = [ "default-configuration.properties", "foo/project001/App.class", "META-INF/MANIFEST.MF", "META-INF/maven/org.apache.maven.plugins/maven-jar-plugin-test-mjar-30-01/pom.properties", - "META-INF/maven/org.apache.maven.plugins/maven-jar-plugin-test-mjar-30-01/pom.xml" }; + "META-INF/maven/org.apache.maven.plugins/maven-jar-plugin-test-mjar-30-01/pom.xml" ]; Set contents = new HashSet(); diff --git a/src/it/MJAR-30-include/verify.bsh b/src/it/MJAR-30-include/verify.groovy similarity index 93% rename from src/it/MJAR-30-include/verify.bsh rename to src/it/MJAR-30-include/verify.groovy index ae3a05e2..28d3e5f3 100644 --- a/src/it/MJAR-30-include/verify.bsh +++ b/src/it/MJAR-30-include/verify.groovy @@ -21,7 +21,6 @@ import java.io.*; import java.util.*; import java.util.jar.*; -import org.codehaus.plexus.util.*; boolean result = true; @@ -41,9 +40,9 @@ try return false; } - String[] artifactNames = new String[] { "service/TestInterface.class", "META-INF/MANIFEST.MF", + String[] artifactNames = [ "service/TestInterface.class", "META-INF/MANIFEST.MF", "META-INF/maven/org.apache.maven.plugins/maven-jar-plugin-test-mjar-30-02/pom.properties", - "META-INF/maven/org.apache.maven.plugins/maven-jar-plugin-test-mjar-30-02/pom.xml" }; + "META-INF/maven/org.apache.maven.plugins/maven-jar-plugin-test-mjar-30-02/pom.xml" ]; Set contents = new HashSet(); diff --git a/src/it/MJAR-307/pom.xml b/src/it/MJAR-307/pom.xml new file mode 100644 index 00000000..d0c36edc --- /dev/null +++ b/src/it/MJAR-307/pom.xml @@ -0,0 +1,47 @@ + + + + 4.0.0 + + org.apache.maven.plugins.jar.it + mjar-307 + jar + 1.0 + it-mjar-307 + + Wrong version of commons-io cause a ClassNotFoundException: org.apache.commons.io.file.attribute.FileTimes + + + yyyyMMdd + ${maven.build.timestamp} + + + + + + org.apache.maven.plugins + maven-jar-plugin + @project.version@ + + + + + diff --git a/src/it/MJAR-307/src/main/java/foo/project003/App.java b/src/it/MJAR-307/src/main/java/foo/project003/App.java new file mode 100644 index 00000000..3a3d1665 --- /dev/null +++ b/src/it/MJAR-307/src/main/java/foo/project003/App.java @@ -0,0 +1,32 @@ +package foo.project003; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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!" ); + } +} diff --git a/src/it/MJAR-307/verify.groovy b/src/it/MJAR-307/verify.groovy new file mode 100644 index 00000000..d75e626d --- /dev/null +++ b/src/it/MJAR-307/verify.groovy @@ -0,0 +1,25 @@ +import java.util.jar.JarFile + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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 target = new File( basedir, "target" ); +def jarFile = new File( target, "mjar-307-1.0.jar" ); + +assert jarFile.exists() diff --git a/src/it/MJAR-60/verify.bsh b/src/it/MJAR-60/verify.groovy similarity index 94% rename from src/it/MJAR-60/verify.bsh rename to src/it/MJAR-60/verify.groovy index 04d1975d..76f19fe8 100644 --- a/src/it/MJAR-60/verify.bsh +++ b/src/it/MJAR-60/verify.groovy @@ -21,7 +21,7 @@ import java.io.*; import java.util.*; import java.util.jar.*; -import org.codehaus.plexus.util.*; +import org.apache.commons.io.*; boolean result = true; @@ -51,7 +51,7 @@ try // Only compare files if ( entry.getName().equals( "META-INF/MANIFEST.MF" ) ) { - String manifest = IOUtil.toString( jar.getInputStream ( entry ) ); + String manifest = IOUtils.toString( jar.getInputStream ( entry ) ); int index = manifest.indexOf( "Class-Path: config/" ); if ( index <= 0 ) { diff --git a/src/it/MJAR-62-toolchain/invoker.properties b/src/it/MJAR-62-toolchain/invoker.properties new file mode 100644 index 00000000..9904dcce --- /dev/null +++ b/src/it/MJAR-62-toolchain/invoker.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +invoker.toolchain.jdk.version = 17 \ No newline at end of file diff --git a/src/it/MJAR-62-toolchain/pom.xml b/src/it/MJAR-62-toolchain/pom.xml new file mode 100644 index 00000000..610d560e --- /dev/null +++ b/src/it/MJAR-62-toolchain/pom.xml @@ -0,0 +1,68 @@ + + + + 4.0.0 + org.apache.maven.plugins + mjar-62 + MJAR-62 + jar + 1.0-SNAPSHOT + + jar plugin it + + + + + junit + junit + 4.13.2 + + + + + + + org.apache.maven.plugins + maven-toolchains-plugin + 3.1.0 + + + + toolchain + + + + + + + 17 + + + + + + + org.apache.maven.plugins + maven-jar-plugin + @project.version@ + + + + diff --git a/src/it/MJAR-62-toolchain/src/main/java/myproject/HelloWorld.java b/src/it/MJAR-62-toolchain/src/main/java/myproject/HelloWorld.java new file mode 100644 index 00000000..fd0ad83c --- /dev/null +++ b/src/it/MJAR-62-toolchain/src/main/java/myproject/HelloWorld.java @@ -0,0 +1,36 @@ +package myproject; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * The classic Hello World App. + */ +public class HelloWorld { + + /** + * Main method. + * + * @param args Not used + */ + public static void main( String[] args ) + { + System.out.println( "Hi!" ); + } +} \ No newline at end of file diff --git a/src/it/MJAR-62-toolchain/verify.groovy b/src/it/MJAR-62-toolchain/verify.groovy new file mode 100644 index 00000000..4fdf714c --- /dev/null +++ b/src/it/MJAR-62-toolchain/verify.groovy @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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.JarFile + +def mrjar = new JarFile(new File(basedir, 'target/mjar-62-1.0-SNAPSHOT.jar')) +def manifest = mrjar.manifest.mainAttributes + +assert manifest.getValue("Build-Jdk-Spec") == "17" +assert manifest.getValue("Build-Tool-Jdk-Spec") == System.getProperty("java.specification.version") diff --git a/src/it/MJAR-70-no-recreation/invoker.properties b/src/it/MJAR-70-no-recreation/invoker.properties index 7036df7d..b0879dab 100644 --- a/src/it/MJAR-70-no-recreation/invoker.properties +++ b/src/it/MJAR-70-no-recreation/invoker.properties @@ -16,5 +16,10 @@ # under the License. # NOTE: The first time, we run up to "integration-test" phase which includes the AntRun execution which saves the -# timestamp of the first JAR for comparision with the timestamp of the JAR from the final "package" invocation. +# timestamp of the first JAR for comparison with the timestamp of the JAR from the final "package" invocation. +# Note: +# Currently the timestamp comparison does not work cause based on a Bug in JDK +# https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8177809 +# So we exclude JDK 1.9 +invoker.java.version = 1.9- invoker.goals = clean integration-test package diff --git a/src/it/MJAR-70-no-recreation/pom.xml b/src/it/MJAR-70-no-recreation/pom.xml index 24a7c665..95e29ca1 100644 --- a/src/it/MJAR-70-no-recreation/pom.xml +++ b/src/it/MJAR-70-no-recreation/pom.xml @@ -34,6 +34,13 @@ + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.11.0 + org.apache.maven.plugins maven-antrun-plugin diff --git a/src/it/MJAR-80-exclude/verify.bsh b/src/it/MJAR-80-exclude/verify.groovy similarity index 94% rename from src/it/MJAR-80-exclude/verify.bsh rename to src/it/MJAR-80-exclude/verify.groovy index 824872e4..8d72e1b5 100644 --- a/src/it/MJAR-80-exclude/verify.bsh +++ b/src/it/MJAR-80-exclude/verify.groovy @@ -21,7 +21,6 @@ import java.io.*; import java.util.*; import java.util.jar.*; -import org.codehaus.plexus.util.*; boolean result = true; @@ -48,10 +47,10 @@ try return false; } - String[] artifactNames = new String[] { "test-default-configuration.properties", + String[] artifactNames = [ "test-default-configuration.properties", "foo/project003/AppTest.class", "foo/project003/AppIntegrationTest.class", "META-INF/MANIFEST.MF", "META-INF/maven/org.apache.maven.plugins/maven-jar-plugin-test-mjar-80-03/pom.properties", - "META-INF/maven/org.apache.maven.plugins/maven-jar-plugin-test-mjar-80-03/pom.xml" }; + "META-INF/maven/org.apache.maven.plugins/maven-jar-plugin-test-mjar-80-03/pom.xml" ]; Set contents = new HashSet(); diff --git a/src/it/MJAR-80-fullcontent/verify.bsh b/src/it/MJAR-80-fullcontent/verify.groovy similarity index 94% rename from src/it/MJAR-80-fullcontent/verify.bsh rename to src/it/MJAR-80-fullcontent/verify.groovy index d8784e22..47523b53 100644 --- a/src/it/MJAR-80-fullcontent/verify.bsh +++ b/src/it/MJAR-80-fullcontent/verify.groovy @@ -21,7 +21,6 @@ import java.io.*; import java.util.*; import java.util.jar.*; -import org.codehaus.plexus.util.*; boolean result = true; @@ -48,10 +47,10 @@ try return false; } - String[] artifactNames = new String[] { "test-default-configuration.properties", + String[] artifactNames = [ "test-default-configuration.properties", "foo/project003/AppTest.class", "foo/project003/AppIntegrationTest.class", "META-INF/MANIFEST.MF", "META-INF/maven/org.apache.maven.plugins/maven-jar-plugin-test-mjar-80-01/pom.properties", - "META-INF/maven/org.apache.maven.plugins/maven-jar-plugin-test-mjar-80-01/pom.xml" }; + "META-INF/maven/org.apache.maven.plugins/maven-jar-plugin-test-mjar-80-01/pom.xml" ]; Set contents = new HashSet(); diff --git a/src/it/MJAR-80-include/verify.bsh b/src/it/MJAR-80-include/verify.groovy similarity index 94% rename from src/it/MJAR-80-include/verify.bsh rename to src/it/MJAR-80-include/verify.groovy index 04d7121c..09294a55 100644 --- a/src/it/MJAR-80-include/verify.bsh +++ b/src/it/MJAR-80-include/verify.groovy @@ -21,7 +21,6 @@ import java.io.*; import java.util.*; import java.util.jar.*; -import org.codehaus.plexus.util.*; boolean result = true; @@ -48,10 +47,10 @@ try return false; } - String[] artifactNames = new String[] { "foo/project003/AppIntegrationTest.class", + String[] artifactNames = [ "foo/project003/AppIntegrationTest.class", "META-INF/MANIFEST.MF", "META-INF/maven/org.apache.maven.plugins/maven-jar-plugin-test-mjar-80-02/pom.properties", - "META-INF/maven/org.apache.maven.plugins/maven-jar-plugin-test-mjar-80-02/pom.xml" }; + "META-INF/maven/org.apache.maven.plugins/maven-jar-plugin-test-mjar-80-02/pom.xml" ]; Set contents = new HashSet(); diff --git a/src/it/MJAR-82/verify.bsh b/src/it/MJAR-82/verify.bsh index 2afd430b..acdbfd9d 100644 --- a/src/it/MJAR-82/verify.bsh +++ b/src/it/MJAR-82/verify.bsh @@ -21,7 +21,6 @@ import java.io.*; import java.util.*; import java.util.jar.*; -import org.codehaus.plexus.util.*; import org.codehaus.plexus.util.cli.*; import org.codehaus.plexus.util.FileUtils; diff --git a/src/it/manifest-content/verify.bsh b/src/it/manifest-content/verify.grovy similarity index 88% rename from src/it/manifest-content/verify.bsh rename to src/it/manifest-content/verify.grovy index 122bfa54..2da7753b 100644 --- a/src/it/manifest-content/verify.bsh +++ b/src/it/manifest-content/verify.grovy @@ -21,10 +21,11 @@ import java.io.*; import java.util.*; import java.util.jar.*; -import org.codehaus.plexus.util.*; +import java.util.zip.*; boolean result = true; + try { File target = new File( basedir, "target" ); @@ -41,16 +42,23 @@ try return false; } - JarFile jar = new JarFile( artifact ); - - Attributes manifest = jar.getManifest().getMainAttributes(); - - if ( !manifest.getValue( new Attributes.Name( "Created-By" ) ).startsWith( "Apache Maven" ) ) + ZipFile zip = new ZipFile( artifact ); + Enumeration resultingEntries = zip.entries(); + if ( !"META-INF/".equals( resultingEntries.nextElement().getName() ) ) + { + System.err.println( "META-INF/ must be first zip entry" ); + return false; + } + if ( !"META-INF/MANIFEST.MF".equals( resultingEntries.nextElement().getName() ) ) { - System.err.println( "Created-By not equals Apache Maven" ); + System.err.println( "META-INF/MANIFEST.MF must be second zip entry" ); return false; } + zip.close(); + JarFile jar = new JarFile( artifact ); + + Attributes manifest = jar.getManifest().getMainAttributes(); if ( !"manifest-content-it".equals( manifest.get( Attributes.Name.SPECIFICATION_TITLE ) ) ) { @@ -84,12 +92,6 @@ try return false; } - if ( !"org.apache.maven.plugins".equals( manifest.get( Attributes.Name.IMPLEMENTATION_VENDOR_ID ) ) ) - { - System.err.println( Attributes.Name.IMPLEMENTATION_VENDOR_ID.toString() + " not equals org.apache.maven.plugins" ); - return false; - } - if ( !"jar plugin it".equals( manifest.get( Attributes.Name.IMPLEMENTATION_VENDOR ) ) ) { System.err.println( Attributes.Name.IMPLEMENTATION_VENDOR.toString() + " not equals jar plugin it" ); diff --git a/src/it/mjar-139/verify.bsh b/src/it/mjar-139/verify.bsh index 0af748a3..8d5555b7 100644 --- a/src/it/mjar-139/verify.bsh +++ b/src/it/mjar-139/verify.bsh @@ -21,7 +21,6 @@ import java.io.*; import java.util.*; import java.util.jar.*; -import org.codehaus.plexus.util.*; boolean result = true; diff --git a/src/it/mjar-71-01/verify.bsh b/src/it/mjar-71-01/verify.groovy similarity index 95% rename from src/it/mjar-71-01/verify.bsh rename to src/it/mjar-71-01/verify.groovy index b62fe5d6..97f78e88 100644 --- a/src/it/mjar-71-01/verify.bsh +++ b/src/it/mjar-71-01/verify.groovy @@ -21,7 +21,7 @@ import java.io.*; import java.util.*; import java.util.jar.*; -import org.codehaus.plexus.util.*; +import org.apache.commons.io.*; boolean result = true; @@ -51,7 +51,7 @@ try // Only compare files if ( entry.getName().equals( "META-INF/MANIFEST.MF" ) ) { - String manifest = IOUtil.toString( jar.getInputStream ( entry ) ); + String manifest = IOUtils.toString( jar.getInputStream ( entry ) ); int index = manifest.indexOf( "Archiver-Version: foobar-1.23456" ); if ( index <= 0 ) { diff --git a/src/it/mjar-71-02/verify.bsh b/src/it/mjar-71-02/verify.groovy similarity index 95% rename from src/it/mjar-71-02/verify.bsh rename to src/it/mjar-71-02/verify.groovy index ada2d78d..33e40531 100644 --- a/src/it/mjar-71-02/verify.bsh +++ b/src/it/mjar-71-02/verify.groovy @@ -21,7 +21,7 @@ import java.io.*; import java.util.*; import java.util.jar.*; -import org.codehaus.plexus.util.*; +import org.apache.commons.io.*; boolean result = true; @@ -51,7 +51,7 @@ try // Only compare files if ( entry.getName().equals ( "META-INF/MANIFEST.MF" ) ) { - String manifest = IOUtil.toString( jar.getInputStream ( entry ) ); + String manifest = IOUtils.toString( jar.getInputStream ( entry ) ); int index = manifest.indexOf( "Archiver-Version: foobar-1.23456" ); if ( index > 0 ) { diff --git a/src/it/mjar-90/verify.bsh b/src/it/mjar-90/verify.bsh index c1e93022..7560e222 100644 --- a/src/it/mjar-90/verify.bsh +++ b/src/it/mjar-90/verify.bsh @@ -21,7 +21,6 @@ import java.io.*; import java.util.*; import java.util.jar.*; -import org.codehaus.plexus.util.*; boolean result = true; diff --git a/src/it/project-004/verify.bsh b/src/it/project-004/verify.groovy similarity index 93% rename from src/it/project-004/verify.bsh rename to src/it/project-004/verify.groovy index ede03208..6989c03e 100644 --- a/src/it/project-004/verify.bsh +++ b/src/it/project-004/verify.groovy @@ -21,7 +21,6 @@ import java.io.*; import java.util.*; import java.util.jar.*; -import org.codehaus.plexus.util.*; boolean result = true; @@ -41,10 +40,10 @@ try return false; } - String[] artifactNames = new String[] { "service/TestInterface.class", + String[] artifactNames = [ "service/TestInterface.class", "service/impl/TestImplementation.class", "TestCompile1.class", "notIncluded.xml", "META-INF/MANIFEST.MF", "META-INF/maven/org.apache.maven.plugins/maven-jar-plugin-test-project-004/pom.properties", - "META-INF/maven/org.apache.maven.plugins/maven-jar-plugin-test-project-004/pom.xml" }; + "META-INF/maven/org.apache.maven.plugins/maven-jar-plugin-test-project-004/pom.xml" ]; Set contents = new HashSet(); @@ -84,10 +83,10 @@ try return false; } - artifactNames = new String[] { "service/TestInterface.class", + artifactNames = [ "service/TestInterface.class", "META-INF/MANIFEST.MF", "META-INF/maven/org.apache.maven.plugins/maven-jar-plugin-test-project-004/pom.properties", - "META-INF/maven/org.apache.maven.plugins/maven-jar-plugin-test-project-004/pom.xml" }; + "META-INF/maven/org.apache.maven.plugins/maven-jar-plugin-test-project-004/pom.xml" ]; contents = new HashSet(); diff --git a/src/main/filtered-resources/META-INF/plexus/components.xml b/src/main/filtered-resources/META-INF/plexus/components.xml index 2665d7f7..e428cbe0 100644 --- a/src/main/filtered-resources/META-INF/plexus/components.xml +++ b/src/main/filtered-resources/META-INF/plexus/components.xml @@ -67,28 +67,28 @@ - org.apache.maven.plugins:maven-resources-plugin:2.7:resources + org.apache.maven.plugins:maven-resources-plugin:${version.maven-resources-plugin}:resources - org.apache.maven.plugins:maven-compiler-plugin:3.5.1:compile + org.apache.maven.plugins:maven-compiler-plugin:${version.maven-compiler-plugin}:compile - org.apache.maven.plugins:maven-resources-plugin:2.7:testResources + org.apache.maven.plugins:maven-resources-plugin:${version.maven-resources-plugin}:testResources - org.apache.maven.plugins:maven-compiler-plugin:3.5.1:testCompile + org.apache.maven.plugins:maven-compiler-plugin:${version.maven-compiler-plugin}:testCompile - org.apache.maven.plugins:maven-surefire-plugin:2.19.1:test + org.apache.maven.plugins:maven-surefire-plugin:${version.maven-surefire}:test org.apache.maven.plugins:maven-jar-plugin:${project.version}:jar - org.apache.maven.plugins:maven-install-plugin:2.5.2:install + org.apache.maven.plugins:maven-install-plugin:${version.maven-install-plugin}:install - org.apache.maven.plugins:maven-deploy-plugin:2.8.2:deploy + org.apache.maven.plugins:maven-deploy-plugin:${version.maven-deploy-plugin}:deploy diff --git a/src/main/java/org/apache/maven/plugins/jar/AbstractJarMojo.java b/src/main/java/org/apache/maven/plugins/jar/AbstractJarMojo.java index a70591e1..9a2bc229 100644 --- a/src/main/java/org/apache/maven/plugins/jar/AbstractJarMojo.java +++ b/src/main/java/org/apache/maven/plugins/jar/AbstractJarMojo.java @@ -1,5 +1,3 @@ -package org.apache.maven.plugins.jar; - /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -9,7 +7,7 @@ * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an @@ -18,6 +16,13 @@ * specific language governing permissions and limitations * under the License. */ +package org.apache.maven.plugins.jar; + +import java.io.File; +import java.nio.file.FileSystems; +import java.util.Arrays; +import java.util.Map; +import java.util.Optional; import org.apache.maven.archiver.MavenArchiveConfiguration; import org.apache.maven.archiver.MavenArchiver; @@ -28,10 +33,12 @@ import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProjectHelper; +import org.apache.maven.shared.model.fileset.FileSet; +import org.apache.maven.shared.model.fileset.util.FileSetManager; +import org.apache.maven.toolchain.ToolchainManager; import org.codehaus.plexus.archiver.Archiver; import org.codehaus.plexus.archiver.jar.JarArchiver; - -import java.io.File; +import org.codehaus.plexus.archiver.util.DefaultFileSet; /** * Base class for creating a jar from project classes. @@ -39,13 +46,21 @@ * @author Emmanuel Venisse * @version $Id$ */ -public abstract class AbstractJarMojo - extends AbstractMojo -{ +public abstract class AbstractJarMojo extends AbstractMojo { - private static final String[] DEFAULT_EXCLUDES = new String[] { "**/package.html" }; + private static final String[] DEFAULT_EXCLUDES = new String[] {"**/package.html"}; - private static final String[] DEFAULT_INCLUDES = new String[] { "**/**" }; + private static final String[] DEFAULT_INCLUDES = new String[] {"**/**"}; + + private static final String MODULE_DESCRIPTOR_FILE_NAME = "module-info.class"; + + private static final String SEPARATOR = FileSystems.getDefault().getSeparator(); + + @Component + private ToolchainsJdkSpecification toolchainsJdkSpecification; + + @Component + private ToolchainManager toolchainManager; /** * List of files to include. Specified as fileset patterns which are relative to the input directory whose contents @@ -64,31 +79,31 @@ public abstract class AbstractJarMojo /** * Directory containing the generated JAR. */ - @Parameter( defaultValue = "${project.build.directory}", required = true ) + @Parameter(defaultValue = "${project.build.directory}", required = true) private File outputDirectory; /** * Name of the generated JAR. */ - @Parameter( defaultValue = "${project.build.finalName}", readonly = true ) + @Parameter(defaultValue = "${project.build.finalName}", readonly = true) private String finalName; /** * The Jar archiver. */ - @Component( role = Archiver.class, hint = "jar" ) - private JarArchiver jarArchiver; + @Component + private Map archivers; /** - * The {@link {MavenProject}. + * The {@link MavenProject}. */ - @Parameter( defaultValue = "${project}", readonly = true, required = true ) + @Parameter(defaultValue = "${project}", readonly = true, required = true) private MavenProject project; /** * The {@link MavenSession}. */ - @Parameter( defaultValue = "${session}", readonly = true, required = true ) + @Parameter(defaultValue = "${session}", readonly = true, required = true) private MavenSession session; /** @@ -102,10 +117,11 @@ public abstract class AbstractJarMojo * Using this property will fail your build cause it has been removed from the plugin configuration. See the * Major Version Upgrade to version 3.0.0 for the * plugin. - * + * * @deprecated For version 3.0.0 this parameter is only defined here to break the build if you use it! */ - @Parameter( property = "jar.useDefaultManifestFile", defaultValue = "false" ) + @Parameter(property = "jar.useDefaultManifestFile", defaultValue = "false") + @Deprecated private boolean useDefaultManifestFile; /** @@ -125,15 +141,67 @@ public abstract class AbstractJarMojo * Starting with 3.0.0 the property has been renamed from jar.forceCreation to * maven.jar.forceCreation. */ - @Parameter( property = "maven.jar.forceCreation", defaultValue = "false" ) + @Parameter(property = "maven.jar.forceCreation", defaultValue = "false") private boolean forceCreation; /** * Skip creating empty archives. */ - @Parameter( defaultValue = "false" ) + @Parameter(defaultValue = "false") private boolean skipIfEmpty; + /** + * Timestamp for reproducible output archive entries, either formatted as ISO 8601 extended offset date-time + * (e.g. in UTC such as '2011-12-03T10:15:30Z' or with an offset '2019-10-05T20:37:42+06:00'), + * or as an int representing seconds since the epoch + * (like SOURCE_DATE_EPOCH). + * + * @since 3.2.0 + */ + @Parameter(defaultValue = "${project.build.outputTimestamp}") + private String outputTimestamp; + + /** + * If the JAR contains the {@code META-INF/versions} directory it will be detected as a multi-release JAR file + * ("MRJAR"), adding the {@code Multi-Release: true} attribute to the main section of the JAR MANIFEST.MF. + * + * @since 3.4.0 + */ + @Parameter(property = "maven.jar.detectMultiReleaseJar", defaultValue = "true") + private boolean detectMultiReleaseJar; + + /** + * If set to {@code false}, the files and directories that by default are excluded from the resulting archive, + * like {@code .gitignore}, {@code .cvsignore} etc. will be included. + * This means all files like the following will be included. + *
    + *
  • Misc: **/*~, **/#*#, **/.#*, **/%*%, **/._*
  • + *
  • CVS: **/CVS, **/CVS/**, **/.cvsignore
  • + *
  • RCS: **/RCS, **/RCS/**
  • + *
  • SCCS: **/SCCS, **/SCCS/**
  • + *
  • VSSercer: **/vssver.scc
  • + *
  • MKS: **/project.pj
  • + *
  • SVN: **/.svn, **/.svn/**
  • + *
  • GNU: **/.arch-ids, **/.arch-ids/**
  • + *
  • Bazaar: **/.bzr, **/.bzr/**
  • + *
  • SurroundSCM: **/.MySCMServerInfo
  • + *
  • Mac: **/.DS_Store
  • + *
  • Serena Dimension: **/.metadata, **/.metadata/**
  • + *
  • Mercurial: **/.hg, **/.hg/**
  • + *
  • Git: **/.git, **/.git/**
  • + *
  • Bitkeeper: **/BitKeeper, **/BitKeeper/**, **/ChangeSet, + * **/ChangeSet/**
  • + *
  • Darcs: **/_darcs, **/_darcs/**, **/.darcsrepo, + * **/.darcsrepo/****/-darcs-backup*, **/.darcs-temp-mail + *
+ * + * @see DEFAULTEXCLUDES + * + * @since 3.4.0 + */ + @Parameter(defaultValue = "true") + private boolean addDefaultExcludes; + /** * Return the specific output directory to serve as the root for the archive. * @return get classes directory. @@ -141,10 +209,11 @@ public abstract class AbstractJarMojo protected abstract File getClassesDirectory(); /** - * @return the {@link #project} + * Return the {@link #project MavenProject} + * + * @return the MavenProject. */ - protected final MavenProject getProject() - { + protected final MavenProject getProject() { return project; } @@ -168,27 +237,17 @@ protected final MavenProject getProject() * @param classifier an optional classifier * @return the file to generate */ - protected File getJarFile( File basedir, String resultFinalName, String classifier ) - { - if ( basedir == null ) - { - throw new IllegalArgumentException( "basedir is not allowed to be null" ); + protected File getJarFile(File basedir, String resultFinalName, String classifier) { + if (basedir == null) { + throw new IllegalArgumentException("basedir is not allowed to be null"); } - if ( resultFinalName == null ) - { - throw new IllegalArgumentException( "finalName is not allowed to be null" ); - } - - StringBuilder fileName = new StringBuilder( resultFinalName ); - - if ( hasClassifier() ) - { - fileName.append( "-" ).append( classifier ); + if (resultFinalName == null) { + throw new IllegalArgumentException("finalName is not allowed to be null"); } - fileName.append( ".jar" ); + String fileName = resultFinalName + (hasClassifier() ? "-" + classifier : "") + ".jar"; - return new File( basedir, fileName.toString() ); + return new File(basedir, fileName); } /** @@ -196,39 +255,74 @@ protected File getJarFile( File basedir, String resultFinalName, String classifi * @return The instance of File for the created archive file. * @throws MojoExecutionException in case of an error. */ - public File createArchive() - throws MojoExecutionException - { - File jarFile = getJarFile( outputDirectory, finalName, getClassifier() ); - - MavenArchiver archiver = new MavenArchiver(); - - archiver.setArchiver( jarArchiver ); + public File createArchive() throws MojoExecutionException { + File jarFile = getJarFile(outputDirectory, finalName, getClassifier()); + + FileSetManager fileSetManager = new FileSetManager(); + FileSet jarContentFileSet = new FileSet(); + jarContentFileSet.setDirectory(getClassesDirectory().getAbsolutePath()); + jarContentFileSet.setIncludes(Arrays.asList(getIncludes())); + jarContentFileSet.setExcludes(Arrays.asList(getExcludes())); + + String[] includedFiles = fileSetManager.getIncludedFiles(jarContentFileSet); + + if (detectMultiReleaseJar + && Arrays.stream(includedFiles) + .anyMatch(p -> p.startsWith("META-INF" + SEPARATOR + "versions" + SEPARATOR))) { + getLog().debug("Adding 'Multi-Release: true' manifest entry."); + archive.addManifestEntry("Multi-Release", "true"); + } - archiver.setOutputFile( jarFile ); + // May give false positives if the files is named as module descriptor + // but is not in the root of the archive or in the versioned area + // (and hence not actually a module descriptor). + // That is fine since the modular Jar archiver will gracefully + // handle such case. + // And also such case is unlikely to happen as file ending + // with "module-info.class" is unlikely to be included in Jar file + // unless it is a module descriptor. + boolean containsModuleDescriptor = + Arrays.stream(includedFiles).anyMatch(p -> p.endsWith(MODULE_DESCRIPTOR_FILE_NAME)); - archive.setForced( forceCreation ); + String archiverName = containsModuleDescriptor ? "mjar" : "jar"; - try - { + MavenArchiver archiver = new MavenArchiver(); + archiver.setCreatedBy("Maven JAR Plugin", "org.apache.maven.plugins", "maven-jar-plugin"); + archiver.setArchiver((JarArchiver) archivers.get(archiverName)); + archiver.setOutputFile(jarFile); + + Optional.ofNullable(toolchainManager.getToolchainFromBuildContext("jdk", session)) + .ifPresent(toolchain -> toolchainsJdkSpecification + .getJDKSpecification(toolchain) + .ifPresent(jdkSpec -> { + archive.addManifestEntry("Build-Jdk-Spec", jdkSpec); + archive.addManifestEntry( + "Build-Tool-Jdk-Spec", System.getProperty("java.specification.version")); + archiver.setBuildJdkSpecDefaultEntry(false); + getLog().info("Set Build-Jdk-Spec based on toolchain in maven-jar-plugin " + toolchain); + })); + + // configure for Reproducible Builds based on outputTimestamp value + archiver.configureReproducibleBuild(outputTimestamp); + + archive.setForced(forceCreation); + + try { File contentDirectory = getClassesDirectory(); - if ( !contentDirectory.exists() ) - { - getLog().warn( "JAR will be empty - no content was marked for inclusion!" ); - } - else - { - archiver.getArchiver().addDirectory( contentDirectory, getIncludes(), getExcludes() ); + if (!contentDirectory.exists()) { + if (!forceCreation) { + getLog().warn("JAR will be empty - no content was marked for inclusion!"); + } + } else { + archiver.getArchiver().addFileSet(getFileSet(contentDirectory)); } - archiver.createArchive( session, project, archive ); + archiver.createArchive(session, project, archive); return jarFile; - } - catch ( Exception e ) - { + } catch (Exception e) { // TODO: improve error handling - throw new MojoExecutionException( "Error assembling JAR", e ); + throw new MojoExecutionException("Error assembling JAR", e); } } @@ -236,81 +330,70 @@ public File createArchive() * Generates the JAR. * @throws MojoExecutionException in case of an error. */ - public void execute() - throws MojoExecutionException - { - if ( useDefaultManifestFile ) - { - throw new MojoExecutionException( "You are using 'useDefaultManifestFile' which has been removed" - + " from the maven-jar-plugin. " - + "Please see the >>Major Version Upgrade to version 3.0.0<< on the plugin site." ); + @Override + public void execute() throws MojoExecutionException { + if (useDefaultManifestFile) { + throw new MojoExecutionException("You are using 'useDefaultManifestFile' which has been removed" + + " from the maven-jar-plugin. " + + "Please see the >>Major Version Upgrade to version 3.0.0<< on the plugin site."); } - if ( skipIfEmpty && ( !getClassesDirectory().exists() || getClassesDirectory().list().length < 1 ) ) - { - getLog().info( "Skipping packaging of the " + getType() ); - } - else - { + if (skipIfEmpty + && (!getClassesDirectory().exists() || getClassesDirectory().list().length < 1)) { + getLog().info("Skipping packaging of the " + getType()); + } else { File jarFile = createArchive(); - if ( hasClassifier() ) - { - projectHelper.attachArtifact( getProject(), getType(), getClassifier(), jarFile ); - } - else - { - if ( projectHasAlreadySetAnArtifact() ) - { - throw new MojoExecutionException( "You have to use a classifier " - + "to attach supplemental artifacts to the project instead of replacing them." ); + if (hasClassifier()) { + projectHelper.attachArtifact(getProject(), getType(), getClassifier(), jarFile); + } else { + if (projectHasAlreadySetAnArtifact()) { + throw new MojoExecutionException("You have to use a classifier " + + "to attach supplemental artifacts to the project instead of replacing them."); } - getProject().getArtifact().setFile( jarFile ); + getProject().getArtifact().setFile(jarFile); } } } - private boolean projectHasAlreadySetAnArtifact() - { - if ( getProject().getArtifact().getFile() != null ) - { - return getProject().getArtifact().getFile().isFile(); - } - else - { + private boolean projectHasAlreadySetAnArtifact() { + if (getProject().getArtifact().getFile() == null) { return false; } + + return getProject().getArtifact().getFile().isFile(); } /** - * @return true in case where the classifier is not {@code null} and contains something else than white spaces. + * Return {@code true} in case where the classifier is not {@code null} and contains something else than white spaces. + * + * @return {@code true} if the classifier is set. */ - protected boolean hasClassifier() - { - boolean result = false; - if ( getClassifier() != null && getClassifier().trim().length() > 0 ) - { - result = true; - } - - return result; + protected boolean hasClassifier() { + return getClassifier() != null && !getClassifier().trim().isEmpty(); } - private String[] getIncludes() - { - if ( includes != null && includes.length > 0 ) - { + private String[] getIncludes() { + if (includes != null && includes.length > 0) { return includes; } return DEFAULT_INCLUDES; } - private String[] getExcludes() - { - if ( excludes != null && excludes.length > 0 ) - { + private String[] getExcludes() { + if (excludes != null && excludes.length > 0) { return excludes; } return DEFAULT_EXCLUDES; } + + private org.codehaus.plexus.archiver.FileSet getFileSet(File contentDirectory) { + DefaultFileSet fileSet = DefaultFileSet.fileSet(contentDirectory) + .prefixed("") + .includeExclude(getIncludes(), getExcludes()) + .includeEmptyDirs(true); + + fileSet.setUsingDefaultExcludes(addDefaultExcludes); + return fileSet; + } } diff --git a/src/main/java/org/apache/maven/plugins/jar/JarMojo.java b/src/main/java/org/apache/maven/plugins/jar/JarMojo.java index 4172028b..7ce06d4e 100644 --- a/src/main/java/org/apache/maven/plugins/jar/JarMojo.java +++ b/src/main/java/org/apache/maven/plugins/jar/JarMojo.java @@ -1,5 +1,3 @@ -package org.apache.maven.plugins.jar; - /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -9,7 +7,7 @@ * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an @@ -18,35 +16,38 @@ * specific language governing permissions and limitations * under the License. */ +package org.apache.maven.plugins.jar; + +import java.io.File; 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 java.io.File; - /** * Build a JAR from the current project. * * @author Emmanuel Venisse * @version $Id$ */ -@Mojo( name = "jar", defaultPhase = LifecyclePhase.PACKAGE, requiresProject = true, threadSafe = true, - requiresDependencyResolution = ResolutionScope.RUNTIME ) -public class JarMojo - extends AbstractJarMojo -{ +@Mojo( + name = "jar", + defaultPhase = LifecyclePhase.PACKAGE, + requiresProject = true, + threadSafe = true, + requiresDependencyResolution = ResolutionScope.RUNTIME) +public class JarMojo extends AbstractJarMojo { /** * Directory containing the classes and resource files that should be packaged into the JAR. */ - @Parameter( defaultValue = "${project.build.outputDirectory}", required = true ) + @Parameter(defaultValue = "${project.build.outputDirectory}", required = true) private File classesDirectory; /** * Classifier to add to the artifact generated. If given, the artifact will be attached * as a supplemental artifact. - * If not given this will create the main artifact which is the default behavior. + * If not given this will create the main artifact which is the default behavior. * If you try to do that a second time without using a classifier the build will fail. */ @Parameter @@ -55,24 +56,24 @@ public class JarMojo /** * {@inheritDoc} */ - protected String getClassifier() - { + @Override + protected String getClassifier() { return classifier; } /** * {@inheritDoc} */ - protected String getType() - { + @Override + protected String getType() { return "jar"; } /** * {@inheritDoc} */ - protected File getClassesDirectory() - { + @Override + protected File getClassesDirectory() { return classesDirectory; } } diff --git a/src/main/java/org/apache/maven/plugins/jar/TestJarMojo.java b/src/main/java/org/apache/maven/plugins/jar/TestJarMojo.java index 5c904497..96b5ac36 100644 --- a/src/main/java/org/apache/maven/plugins/jar/TestJarMojo.java +++ b/src/main/java/org/apache/maven/plugins/jar/TestJarMojo.java @@ -1,5 +1,3 @@ -package org.apache.maven.plugins.jar; - /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -9,7 +7,7 @@ * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an @@ -18,8 +16,10 @@ * specific language governing permissions and limitations * under the License. */ +package org.apache.maven.plugins.jar; import java.io.File; + import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; @@ -33,67 +33,66 @@ * @version $Id$ */ // CHECKSTYLE_OFF: LineLength -@Mojo( name = "test-jar", defaultPhase = LifecyclePhase.PACKAGE, requiresProject = true, threadSafe = true, requiresDependencyResolution = ResolutionScope.TEST ) +@Mojo( + name = "test-jar", + defaultPhase = LifecyclePhase.PACKAGE, + requiresProject = true, + threadSafe = true, + requiresDependencyResolution = ResolutionScope.TEST) // CHECKSTYLE_ON: LineLength -public class TestJarMojo - extends AbstractJarMojo -{ +public class TestJarMojo extends AbstractJarMojo { /** * Set this to true to bypass test-jar generation. Its use is NOT RECOMMENDED, but quite * convenient on occasion. */ - @Parameter( property = "maven.test.skip" ) + @Parameter(property = "maven.test.skip") private boolean skip; /** * Directory containing the test classes and resource files that should be packaged into the JAR. */ - @Parameter( defaultValue = "${project.build.testOutputDirectory}", required = true ) + @Parameter(defaultValue = "${project.build.testOutputDirectory}", required = true) private File testClassesDirectory; /** - * Classifier to used for {@code test-jar}. + * Classifier to use for {@code test-jar}. */ - @Parameter( defaultValue = "tests" ) + @Parameter(defaultValue = "tests") private String classifier; /** * {@inheritDoc} */ - protected String getClassifier() - { + @Override + protected String getClassifier() { return classifier; } /** * {@inheritDoc} */ - protected String getType() - { + @Override + protected String getType() { return "test-jar"; } /** * {@inheritDoc} */ - protected File getClassesDirectory() - { + @Override + protected File getClassesDirectory() { return testClassesDirectory; } /** * {@inheritDoc} */ - public void execute() - throws MojoExecutionException - { - if ( skip ) - { - getLog().info( "Skipping packaging of the test-jar" ); - } - else - { + @Override + public void execute() throws MojoExecutionException { + if (skip) { + getLog().info("Skipping packaging of the test-jar"); + } else { super.execute(); } } diff --git a/src/main/java/org/apache/maven/plugins/jar/ToolchainsJdkSpecification.java b/src/main/java/org/apache/maven/plugins/jar/ToolchainsJdkSpecification.java new file mode 100644 index 00000000..ef992ab0 --- /dev/null +++ b/src/main/java/org/apache/maven/plugins/jar/ToolchainsJdkSpecification.java @@ -0,0 +1,110 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.maven.plugins.jar; + +import javax.inject.Named; +import javax.inject.Singleton; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.UncheckedIOException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +import org.apache.maven.toolchain.Toolchain; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Component provided JDK specification based on toolchains. + */ +@Named +@Singleton +class ToolchainsJdkSpecification { + + private final Logger logger = LoggerFactory.getLogger(ToolchainsJdkSpecification.class); + + private final Map cache = new HashMap<>(); + + public synchronized Optional getJDKSpecification(Toolchain toolchain) { + Optional javacPath = getJavacPath(toolchain); + return javacPath.map(path -> cache.computeIfAbsent(path, this::getSpecForPath)); + } + + private Optional getJavacPath(Toolchain toolchain) { + return Optional.ofNullable(toolchain.findTool("javac")).map(Paths::get).map(this::getCanonicalPath); + } + + private Path getCanonicalPath(Path path) { + try { + return path.toRealPath(); + } catch (IOException e) { + if (path.getParent() != null) { + return getCanonicalPath(path.getParent()).resolve(path.getFileName()); + } else { + throw new UncheckedIOException(e); + } + } + } + + private String getSpecForPath(Path path) { + try { + ProcessBuilder processBuilder = new ProcessBuilder(path.toString(), "-version"); + processBuilder.redirectErrorStream(true); + Process process = processBuilder.start(); + String version = readOutput(process.getInputStream()).trim(); + process.waitFor(); + + if (version.startsWith("javac ")) { + version = version.substring(6); + if (version.startsWith("1.")) { + version = version.substring(0, 3); + } else { + version = version.substring(0, 2); + } + return version; + } else { + logger.warn("Unrecognized output from {}: {}", processBuilder.command(), version); + } + } catch (IndexOutOfBoundsException | IOException e) { + logger.warn("Failed to execute: {} - {}", path, e.getMessage()); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + + return null; + } + + private String readOutput(InputStream inputstream) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(inputstream)); + + StringBuilder output = new StringBuilder(); + String line; + while ((line = br.readLine()) != null) { + output.append(line + System.lineSeparator()); + } + + return output.toString(); + } +} diff --git a/src/site/apt/examples/create-test-jar.apt.vm b/src/site/apt/examples/create-test-jar.apt.vm index 27b3f0d3..2bee6f8a 100644 --- a/src/site/apt/examples/create-test-jar.apt.vm +++ b/src/site/apt/examples/create-test-jar.apt.vm @@ -28,15 +28,15 @@ How to create a jar containing test classes - When you want to create a jar containing test-classes, you would probably want to reuse those classes. + When you want to create a jar containing , you would probably want to reuse those classes. There are two ways to solve this: - * Create an attached jar with the test-classes from the current project and loose its transitive <<>>-scoped dependencies. + * Create an attached jar with the from the current project and loose its transitive <<>>-scoped dependencies. - * Create a separate project with the test-classes. + * Create a separate project with the . [] - + * The easy way You can produce a jar which will include your test classes and resources. @@ -75,6 +75,7 @@ How to create a jar containing test classes groupId artifactId + tests test-jar version test @@ -84,9 +85,17 @@ How to create a jar containing test classes
+-----------------+ + Based on such configuration there will be two jar files generated. The first one contains the + classes from <<>> whereas the second one will contain the classes from <<>>. + The generated jar files follow the naming schema <<>> for the first one and + <<>> for the second one. The parts <<>>, <<>> + will be replaced by the values given within your project <<>> file. The <<>> + will be set to <<>> which is a default of the maven-jar-plugin which can be changed if you need by + {{{../test-jar-mojo.html}using the configuration in the jar goal}}. + <> The downside of this solution is that you don't get the transitive <<>>-scoped dependencies automatically. Maven only resolves the <<>>-time dependencies, so you'll have to add all the other required <<>>-scoped dependencies by hand. - + * The preferred way In order to let Maven resolve all <<>>-scoped transitive dependencies you should create a separate project. @@ -100,14 +109,17 @@ How to create a jar containing test classes +-----------------+ - * Move the sources files from <<>> you want to share from the original project to the <<>> of this project. + * Move the sources files from <<>> you want to share from + the original project to the <<>> of this project. The same type of movement counts for the resources as well of course. - * Move the required <<>>-scoped dependencies and from the original project to this project and remove the scope (i.e. changing it to the <<>>-scope). - And yes, that means that the junit dependency (or any other testing framework dependency) gets the default scope too. - You'll probably need to add some project specific dependencies as well to let it all compile again. + * Move the required <<>>-scoped dependencies from the original + project to this project and remove the scope (i.e. changing it to the <<>>-scope). + And yes, that means that the junit dependency (or any other testing + framework dependency) gets the default scope too. You'll probably need + to add some project specific dependencies as well to let it all compile again. - Now you have your reusable test-classes and you can refer to it as you're used to: + Now you have your reusable and you can refer to it as you're used to: +-----------------+ diff --git a/src/site/apt/index.apt.vm b/src/site/apt/index.apt.vm index 44826915..6b7bd44c 100644 --- a/src/site/apt/index.apt.vm +++ b/src/site/apt/index.apt.vm @@ -29,7 +29,7 @@ ${project.name} This plugin provides the capability to build jars. - If you like to sign jars please use the + To sign jars, use the {{{/plugins/maven-jarsigner-plugin/}Maven Jarsigner Plugin}}. * Goals Overview @@ -38,63 +38,28 @@ ${project.name} * {{{./test-jar-mojo.html}jar:test-jar}} create a jar file for your project test classes . - [] - -* Major Version Upgrade to version 3.0.0 - - Please note that the following parameter has been completely removed from the plugin configuration: - - * useDefaultManifestFile - - If you need to define your own <> file you can simply achieve that via - {{{http://maven.apache.org/shared/maven-archiver/index.html}Maven Archiver}} configuration - like in the following example: - -+-----------------+ - - ... - - - - org.apache.maven.plugins - maven-jar-plugin - ${project.version} - - - \${project.build.outputDirectory}/META-INF/MANIFEST.MF - - - ... - - - - ... - -+-----------------+ * Usage General instructions on how to use the JAR Plugin can be found on the {{{./usage.html}usage page}}. Some more - specific use cases are described in the examples given below. Last but not least, users occasionally contribute - additional examples, tips or errata to the - {{{http://docs.codehaus.org/display/MAVENUSER/JAR+Plugin}plugin's wiki page}}. + specific use cases are described in the examples below. In case you still have questions regarding the plugin's usage, please have a look at the {{{./faq.html}FAQ}} and feel - free to contact the {{{./mail-lists.html}user mailing list}}. The posts to the mailing list are archived and could + 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}}. + the {{{./mailing-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-tracking.html}issue tracker}}. When creating a new issue, please provide a comprehensive description of your + If you feel like the plugin is missing a feature or has a defect, you can file a feature request or bug report in our + {{{https://issues.apache.org/jira/projects/MJAR/issues}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. + 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 - {{{./source-repository.html}source repository}} and will find supplementary information in the + {{{./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}}. * Archiver Configuration - The plugin use Maven Archiver to handle jar content and manifest configuration. + The plugin uses Maven Archiver to handle jar content and manifest configuration. You can have a look at the {{{/shared/maven-archiver/}Maven Archiver Documentation}} to understand how to setup this. diff --git a/src/site/apt/usage.apt.vm b/src/site/apt/usage.apt.vm index 69ab5718..ee7284b8 100644 --- a/src/site/apt/usage.apt.vm +++ b/src/site/apt/usage.apt.vm @@ -78,3 +78,22 @@ mvn package the {{{/guides/introduction/introduction-to-the-lifecycle.html}Maven Build Life Cycle}}. For full documentation, click {{{./plugin-info.html}here}}. + +* Modular JAR files + + The {{{https://openjdk.java.net/projects/jigsaw/spec/}Java Platform Module System (JPMS)}} introduced + {{{https://cr.openjdk.java.net/~mr/jigsaw/spec/jar.html}changes in the JAR file specifications}} + as well - Modular JAR files. Modular JAR files are JAR files with <<>> file in the root directory + (or in the versioned area for multi-release JAR files). If the project contains <<>> + the resulting JAR will be a Modular JAR without a need for any configuration regardless of the plugin version used. + + Starting with version 3.1.2, if the JAR file contains <<>>, this plugin will update + the modular descriptor (<<>>) with additional attributes such as the list of packages included + and will validate the resulting modular descriptor (for example if all services provided by the module are actually + included in the JAR file). The most notable additional attribute added is the module main class. + If the JAR manifest contains <<>> attribute this plugin will set the module main class to the same value + (for example how to set it read {{{../../shared/maven-archiver/examples/classpath.html}Make The Jar Executable}}). + Internally the plugin uses the JDK <<>> tool so in order to add the additional attributes and to + verify the modular descriptor Maven should be run with JDK version 9 or newer. If version 8 or earlier is used + the resulting JAR still will be Modular JAR (as it contains <<>>) but no additional attributes + will be added and no validation will be performed. diff --git a/src/site/site.xml b/src/site/site.xml index 7c868e1b..fcb02d6a 100644 --- a/src/site/site.xml +++ b/src/site/site.xml @@ -19,9 +19,9 @@ specific language governing permissions and limitations under the License. --> - + xsi:schemaLocation="http://maven.apache.org/DECORATION/1.8.1 http://maven.apache.org/xsd/decoration-1.8.1.xsd"> @@ -29,13 +29,13 @@ under the License. - + - + - + diff --git a/src/site/xdoc/download.xml.vm b/src/site/xdoc/download.xml.vm index 09d4f421..8f28f053 100644 --- a/src/site/xdoc/download.xml.vm +++ b/src/site/xdoc/download.xml.vm @@ -23,102 +23,51 @@ under the License. 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.

- -

You will be prompted for a mirror - if the file is not found on yours, please be patient, as it may take 24 - hours to reach all mirrors.

- -

In order to guard against corrupted downloads/installations, it is highly recommended to - verify the signature - of the release bundles against the public KEYS used by the Apache Maven - developers.

+

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

-

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

+

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

-

We strongly encourage our users to configure a Maven repository mirror closer to their location, please read How to Use Mirrors for Repositories.

- - - - -

- [if-any logo] - - logo - - [end] - The currently selected mirror is - [preferred]. - If you encounter a problem with this mirror, - please select another mirror. - If all mirrors are failing, there are - backup - mirrors - (at the end of the mirrors list) that should be available. -

+

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

-
- Other mirrors: - - -
+

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

-

- You may also consult the - complete list of - mirrors. + + +

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

+ + + + + + + + + + + + + + + + + + +
LinkChecksumSignature
${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.

- - - -

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

- - - - - - - - - - - - - - - - - - -
LinkChecksumSignature
${project.name} ${project.version} (Source zip)maven/plugins/${project.artifactId}-${project.version}-source-release.zipmaven/plugins/${project.artifactId}-${project.version}-source-release.zip.md5maven/plugins/${project.artifactId}-${project.version}-source-release.zip.asc
-
- -

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

- +

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.

diff --git a/src/test/java/org/apache/maven/plugins/jar/JarMojoTest.java b/src/test/java/org/apache/maven/plugins/jar/JarMojoTest.java index ed4cc9a1..b8b57e88 100644 --- a/src/test/java/org/apache/maven/plugins/jar/JarMojoTest.java +++ b/src/test/java/org/apache/maven/plugins/jar/JarMojoTest.java @@ -1,5 +1,3 @@ -package org.apache.maven.plugins.jar; - /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -9,7 +7,7 @@ * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an @@ -18,47 +16,30 @@ * specific language governing permissions and limitations * under the License. */ +package org.apache.maven.plugins.jar; -import java.io.File; +import org.apache.maven.plugin.testing.junit5.InjectMojo; +import org.apache.maven.plugin.testing.junit5.MojoTest; +import org.junit.jupiter.api.Test; -import org.apache.maven.plugin.testing.AbstractMojoTestCase; -import org.apache.maven.plugins.jar.JarMojo; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; /** * Test for {@link JarMojo} * * @version $Id$ */ -public class JarMojoTest - extends AbstractMojoTestCase -{ - private File testPom = new File( getBasedir(), "src/test/resources/unit/jar-basic-test/pom.xml" ); - - protected void setUp() - throws Exception - { - - // required for mojo lookups to work - super.setUp(); - - } +@MojoTest +class JarMojoTest { /** - * tests the proper discovery and configuration of the mojo - * - * @throws Exception + * Tests the discovery and configuration of the mojo. */ - public void testJarTestEnvironment() - throws Exception - { - - // File pom = new File( getBasedir(), "src/test/resources/unit/clean/pom.xml" ); - - JarMojo mojo = (JarMojo) lookupMojo( "jar", testPom ); - - assertNotNull( mojo ); - - assertEquals( "foo", mojo.getProject().getGroupId() ); + @Test + @InjectMojo(goal = "jar", pom = "classpath:/unit/jar-basic-test/pom.xml") + void testJarTestEnvironment(JarMojo mojo) { + assertNotNull(mojo); + assertEquals("foo", mojo.getProject().getGroupId()); } - } diff --git a/src/test/java/org/apache/maven/plugins/jar/MockArtifact.java b/src/test/java/org/apache/maven/plugins/jar/MockArtifact.java deleted file mode 100644 index fac8d624..00000000 --- a/src/test/java/org/apache/maven/plugins/jar/MockArtifact.java +++ /dev/null @@ -1,303 +0,0 @@ -package org.apache.maven.plugins.jar; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT 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.File; -import java.util.Collection; -import java.util.List; - -import org.apache.maven.artifact.Artifact; -import org.apache.maven.artifact.handler.ArtifactHandler; -import org.apache.maven.artifact.metadata.ArtifactMetadata; -import org.apache.maven.artifact.repository.ArtifactRepository; -import org.apache.maven.artifact.resolver.filter.ArtifactFilter; -import org.apache.maven.artifact.versioning.ArtifactVersion; -import org.apache.maven.artifact.versioning.OverConstrainedVersionException; -import org.apache.maven.artifact.versioning.VersionRange; - -/** - * @todo move to maven-artifact-test - */ -class MockArtifact - implements Artifact -{ - private String groupId; - - private String artifactId; - - private String version; - - private File file; - - private String scope; - - private String type; - - private String classifier; - - private String baseVersion; - - public String getGroupId() - { - return groupId; - } - - public String getArtifactId() - { - return artifactId; - } - - public String getVersion() - { - return version; - } - - public void setVersion( String string ) - { - this.version = string; - } - - public String getScope() - { - return scope; - } - - public String getType() - { - return type; - } - - public String getClassifier() - { - return classifier; - } - - public boolean hasClassifier() - { - return classifier != null; - } - - public File getFile() - { - return file; - } - - public void setFile( File file ) - { - this.file = file; - } - - public String getBaseVersion() - { - return baseVersion; - } - - public void setBaseVersion( String string ) - { - this.baseVersion = string; - } - - public String getId() - { - return null; - } - - public String getDependencyConflictId() - { - return null; - } - - public void addMetadata( ArtifactMetadata artifactMetadata ) - { - // intentionally empty. - } - - public Collection getMetadataList() - { - return null; //To change body of implemented methods use File | Settings | File Templates. - } - - public void setRepository( ArtifactRepository artifactRepository ) - { - //To change body of implemented methods use File | Settings | File Templates. - } - - public ArtifactRepository getRepository() - { - return null; //To change body of implemented methods use File | Settings | File Templates. - } - - public void updateVersion( String string, ArtifactRepository artifactRepository ) - { - //To change body of implemented methods use File | Settings | File Templates. - } - - public String getDownloadUrl() - { - return null; //To change body of implemented methods use File | Settings | File Templates. - } - - public void setDownloadUrl( String string ) - { - //To change body of implemented methods use File | Settings | File Templates. - } - - public ArtifactFilter getDependencyFilter() - { - return null; //To change body of implemented methods use File | Settings | File Templates. - } - - public void setDependencyFilter( ArtifactFilter artifactFilter ) - { - //To change body of implemented methods use File | Settings | File Templates. - } - - public ArtifactHandler getArtifactHandler() - { - return null; //To change body of implemented methods use File | Settings | File Templates. - } - - public List getDependencyTrail() - { - return null; //To change body of implemented methods use File | Settings | File Templates. - } - - public void setDependencyTrail( List list ) - { - //To change body of implemented methods use File | Settings | File Templates. - } - - public void setScope( String string ) - { - //To change body of implemented methods use File | Settings | File Templates. - } - - public VersionRange getVersionRange() - { - return null; //To change body of implemented methods use File | Settings | File Templates. - } - - public void setVersionRange( VersionRange versionRange ) - { - //To change body of implemented methods use File | Settings | File Templates. - } - - public void selectVersion( String string ) - { - //To change body of implemented methods use File | Settings | File Templates. - } - - public boolean isSnapshot() - { - return false; //To change body of implemented methods use File | Settings | File Templates. - } - - public void setResolved( boolean b ) - { - //To change body of implemented methods use File | Settings | File Templates. - } - - public boolean isResolved() - { - return false; //To change body of implemented methods use File | Settings | File Templates. - } - - public void setResolvedVersion( String string ) - { - //To change body of implemented methods use File | Settings | File Templates. - } - - public void setArtifactHandler( ArtifactHandler artifactHandler ) - { - //To change body of implemented methods use File | Settings | File Templates. - } - - public boolean isRelease() - { - return false; //To change body of implemented methods use File | Settings | File Templates. - } - - public void setRelease( boolean b ) - { - //To change body of implemented methods use File | Settings | File Templates. - } - - public List getAvailableVersions() - { - return null; //To change body of implemented methods use File | Settings | File Templates. - } - - public void setAvailableVersions( List list ) - { - //To change body of implemented methods use File | Settings | File Templates. - } - - public boolean isOptional() - { - return false; //To change body of implemented methods use File | Settings | File Templates. - } - - public void setOptional( boolean b ) - { - //To change body of implemented methods use File | Settings | File Templates. - } - - public ArtifactVersion getSelectedVersion() - throws OverConstrainedVersionException - { - return null; //To change body of implemented methods use File | Settings | File Templates. - } - - public boolean isSelectedVersionKnown() - throws OverConstrainedVersionException - { - return false; //To change body of implemented methods use File | Settings | File Templates. - } - - public void setGroupId( String groupId ) - { - this.groupId = groupId; - } - - public void setArtifactId( String artifactId ) - { - this.artifactId = artifactId; - } - - public void setType( String type ) - { - this.type = type; - } - - public void setClassifier( String classifier ) - { - this.classifier = classifier; - } - - public int compareTo( Artifact o ) - { - return 0; - } - - public ArtifactMetadata getMetadata( Class metadataClass ) - { - return null; - } -} diff --git a/src/test/java/org/apache/maven/plugins/jar/ToolchainsJdkVersionTest.java b/src/test/java/org/apache/maven/plugins/jar/ToolchainsJdkVersionTest.java new file mode 100644 index 00000000..0d504ed1 --- /dev/null +++ b/src/test/java/org/apache/maven/plugins/jar/ToolchainsJdkVersionTest.java @@ -0,0 +1,88 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.maven.plugins.jar; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Locale; +import java.util.Optional; + +import org.apache.maven.toolchain.Toolchain; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Assumptions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class ToolchainsJdkVersionTest { + + @Mock + private Toolchain toolchain; + + private final ToolchainsJdkSpecification toolchainsJdkSpecification = new ToolchainsJdkSpecification(); + + @Test + void shouldReturnCorrectSpec() { + + Path javacPath = getJavacPath(); + Assumptions.assumeTrue(Files.isExecutable(javacPath)); + + when(toolchain.findTool("javac")).thenReturn(javacPath.toString()); + + Optional jdkVersion = toolchainsJdkSpecification.getJDKSpecification(toolchain); + Assertions.assertTrue(jdkVersion.isPresent()); + Assertions.assertEquals(System.getProperty("java.specification.version"), jdkVersion.get()); + } + + @Test + void shouldReturnEmptySpec() { + + when(toolchain.findTool("javac")).thenReturn(null); + + Optional jdkVersion = toolchainsJdkSpecification.getJDKSpecification(toolchain); + Assertions.assertFalse(jdkVersion.isPresent()); + } + + private String getJavaCName() { + if (System.getProperty("os.name", "").toLowerCase(Locale.ROOT).startsWith("win")) { + return "javac.exe"; + } else { + return "javac"; + } + } + + private Path getJavacPath() { + String javaCName = getJavaCName(); + + String javaHome = System.getProperty("java.home"); + + Path javacPath = Paths.get(javaHome, "bin", javaCName); + if (Files.isExecutable(javacPath)) { + return javacPath; + } + + // try with jre + return Paths.get(javaHome, "../bin", javaCName); + } +}