├── .asf.yaml ├── .git-blame-ignore-revs ├── .github ├── ISSUE_TEMPLATE │ ├── BUG.yml │ ├── FEATURE.yml │ └── config.yml ├── dependabot.yml ├── pull_request_template.md ├── release-drafter-3.x.yml ├── release-drafter.yml └── workflows │ ├── maven-verify.yml │ ├── pr-automation.yml │ ├── release-drafter.yml │ └── stale.yml ├── .gitignore ├── Jenkinsfile ├── LICENSE ├── NOTICE ├── README.md ├── pom.xml └── src ├── main └── java │ └── org │ └── apache │ └── maven │ └── shared │ └── archiver │ ├── ManifestConfiguration.java │ ├── ManifestSection.java │ ├── MavenArchiveConfiguration.java │ ├── MavenArchiver.java │ ├── MavenArchiverException.java │ └── PomPropertiesUtil.java ├── site ├── apt │ └── examples │ │ ├── classpath.apt │ │ ├── manifest.apt │ │ ├── manifestEntries.apt │ │ ├── manifestFile.apt │ │ └── manifestSections.apt ├── resources │ └── download.cgi ├── site.xml └── xdoc │ ├── download.xml.vm │ └── index.xml.vm └── test ├── java └── org │ └── apache │ └── maven │ └── shared │ └── archiver │ ├── ManifestConfigurationTest.java │ ├── MavenArchiveConfigurationTest.java │ ├── MavenArchiverTest.java │ └── PomPropertiesUtilTest.java └── resources ├── custom-pom.properties ├── dummy.dot-1.5.jar ├── dummy1-1.0.jar ├── dummy1-1.1-20081022.112233-1.jar ├── dummy2-1.5.jar ├── dummy3-2.0.jar └── pom.xml /.asf.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Licensed to the Apache Software Foundation (ASF) under one or more 3 | # contributor license agreements. See the NOTICE file distributed with 4 | # this work for additional information regarding copyright ownership. 5 | # The ASF licenses this file to You under the Apache License, Version 2.0 6 | # (the "License"); you may not use this file except in compliance with 7 | # the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | # see https://s.apache.org/asfyaml 18 | github: 19 | description: "Apache Maven Archiver" 20 | homepage: https://maven.apache.org/shared/maven-archiver/ 21 | labels: 22 | - java 23 | - build-management 24 | - maven-shared 25 | - maven 26 | enabled_merge_buttons: 27 | squash: true 28 | merge: false 29 | rebase: true 30 | autolink_jira: 31 | - MSHARED 32 | del_branch_on_merge: true 33 | features: 34 | issues: true 35 | notifications: 36 | commits: commits@maven.apache.org 37 | issues: issues@maven.apache.org 38 | pullrequests: issues@maven.apache.org 39 | jira_options: link label comment 40 | -------------------------------------------------------------------------------- /.git-blame-ignore-revs: -------------------------------------------------------------------------------- 1 | # 2 | # Licensed to the Apache Software Foundation (ASF) under one 3 | # or more contributor license agreements. See the NOTICE file 4 | # distributed with this work for additional information 5 | # regarding copyright ownership. The ASF licenses this file 6 | # to you under the Apache License, Version 2.0 (the 7 | # "License"); you may not use this file except in compliance 8 | # with the License. You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, 13 | # software distributed under the License is distributed on an 14 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | # KIND, either express or implied. See the License for the 16 | # specific language governing permissions and limitations 17 | # under the License. 18 | # 19 | 20 | # Change maven code style 21 | 670da42432fbfd2d28b29458095716a117d27b7c 22 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/BUG.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Licensed to the Apache Software Foundation (ASF) under one or more 3 | # contributor license agreements. See the NOTICE file distributed with 4 | # this work for additional information regarding copyright ownership. 5 | # The ASF licenses this file to You under the Apache License, Version 2.0 6 | # (the "License"); you may not use this file except in compliance with 7 | # the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | # https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema 19 | 20 | name: Bug Report 21 | description: File a bug report 22 | labels: ["bug"] 23 | 24 | body: 25 | - type: markdown 26 | attributes: 27 | value: | 28 | Thanks for taking the time to fill out this bug report. 29 | 30 | Simple fixes in single PRs do not require issues. 31 | 32 | **Do you use the latest project version?** 33 | 34 | - type: input 35 | id: version 36 | attributes: 37 | label: Affected version 38 | validations: 39 | required: true 40 | 41 | - type: textarea 42 | id: message 43 | attributes: 44 | label: Bug description 45 | validations: 46 | required: true 47 | 48 | 49 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/FEATURE.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Licensed to the Apache Software Foundation (ASF) under one or more 3 | # contributor license agreements. See the NOTICE file distributed with 4 | # this work for additional information regarding copyright ownership. 5 | # The ASF licenses this file to You under the Apache License, Version 2.0 6 | # (the "License"); you may not use this file except in compliance with 7 | # the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | # https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema 19 | 20 | name: Feature request 21 | description: File a proposal for new feature, improvement 22 | labels: ["enhancement"] 23 | 24 | body: 25 | - type: markdown 26 | attributes: 27 | value: | 28 | Thanks for taking the time to fill out this new feature, improvement proposal. 29 | 30 | - type: textarea 31 | id: message 32 | attributes: 33 | label: New feature, improvement proposal 34 | validations: 35 | required: true 36 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Licensed to the Apache Software Foundation (ASF) under one or more 3 | # contributor license agreements. See the NOTICE file distributed with 4 | # this work for additional information regarding copyright ownership. 5 | # The ASF licenses this file to You under the Apache License, Version 2.0 6 | # (the "License"); you may not use this file except in compliance with 7 | # the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | # https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/configuring-issue-templates-for-your-repository#configuring-the-template-chooser 19 | 20 | blank_issues_enabled: false 21 | 22 | contact_links: 23 | 24 | - name: Project Mailing Lists 25 | url: https://maven.apache.org/mailing-lists.html 26 | about: Please ask a question or discuss here 27 | 28 | - name: Old JIRA Issues 29 | url: https://issues.apache.org/jira/issues/?jql=project%3DMSHARED+AND+component%3Dmaven-archiver 30 | about: Please search old JIRA issues 31 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | version: 2 19 | updates: 20 | - package-ecosystem: "maven" 21 | directory: "/" 22 | schedule: 23 | interval: "daily" 24 | ignore: 25 | # Ignore Maven Core updates 26 | - dependency-name: "org.apache.maven:*" 27 | - package-ecosystem: "github-actions" 28 | directory: "/" 29 | schedule: 30 | interval: "daily" 31 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | Following this checklist to help us incorporate your 2 | contribution quickly and easily: 3 | 4 | - [ ] Your pull request should address just one issue, without pulling in other changes. 5 | - [ ] Write a pull request description that is detailed enough to understand what the pull request does, how, and why. 6 | - [ ] Each commit in the pull request should have a meaningful subject line and body. 7 | Note that commits might be squashed by a maintainer on merge. 8 | - [ ] Write unit tests that match behavioral changes, where the tests fail if the changes to the runtime are not applied. 9 | This may not always be possible but is a best-practice. 10 | - [ ] Run `mvn verify` to make sure basic checks pass. 11 | A more thorough check will be performed on your pull request automatically. 12 | - [ ] You have run the integration tests successfully (`mvn -Prun-its verify`). 13 | 14 | If your pull request is about ~20 lines of code you don't need to sign an 15 | [Individual Contributor License Agreement](https://www.apache.org/licenses/icla.pdf) if you are unsure 16 | please ask on the developers list. 17 | 18 | To make clear that you license your contribution under 19 | the [Apache License Version 2.0, January 2004](http://www.apache.org/licenses/LICENSE-2.0) 20 | you have to acknowledge this by using the following check-box. 21 | 22 | - [ ] 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) 23 | - [ ] In any other case, please file an [Apache Individual Contributor License Agreement](https://www.apache.org/licenses/icla.pdf). 24 | -------------------------------------------------------------------------------- /.github/release-drafter-3.x.yml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | _extends: maven-gh-actions-shared:.github/release-drafter.yml 19 | -------------------------------------------------------------------------------- /.github/release-drafter.yml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | _extends: maven-gh-actions-shared 19 | 20 | include-pre-releases: true 21 | prerelease: true 22 | -------------------------------------------------------------------------------- /.github/workflows/maven-verify.yml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | name: Verify 19 | 20 | on: 21 | push: 22 | pull_request: 23 | 24 | jobs: 25 | build: 26 | name: Verify 27 | uses: apache/maven-gh-actions-shared/.github/workflows/maven-verify.yml@v4 28 | with: 29 | ff-maven: "4.0.0-rc-1" # Maven version for fail-fast-build 30 | maven-matrix: '[ "4.0.0-rc-1" ]' 31 | jdk-matrix: '[ "17", "21" ]' 32 | ff-goal: verify 33 | verify-goal: verify 34 | -------------------------------------------------------------------------------- /.github/workflows/pr-automation.yml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | name: PR Automation 19 | on: 20 | pull_request_target: 21 | types: 22 | - closed 23 | 24 | jobs: 25 | pr-automation: 26 | name: PR Automation 27 | uses: apache/maven-gh-actions-shared/.github/workflows/pr-automation.yml@v4 28 | -------------------------------------------------------------------------------- /.github/workflows/release-drafter.yml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | name: Release Drafter 19 | on: 20 | push: 21 | branches: 22 | - master 23 | workflow_dispatch: 24 | 25 | jobs: 26 | update_release_draft: 27 | uses: apache/maven-gh-actions-shared/.github/workflows/release-drafter.yml@v4 28 | -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | name: Stale 19 | 20 | on: 21 | schedule: 22 | - cron: '19 3 * * *' 23 | issue_comment: 24 | types: [ 'created' ] 25 | 26 | jobs: 27 | stale: 28 | uses: 'apache/maven-gh-actions-shared/.github/workflows/stale.yml@v4' 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | .project 3 | .classpath 4 | .settings/ 5 | .svn/ 6 | bin/ 7 | # Intellij 8 | *.ipr 9 | *.iml 10 | .idea 11 | out/ 12 | .DS_Store 13 | /bootstrap 14 | /dependencies.xml 15 | .java-version 16 | .checkstyle 17 | .apt_generated/ 18 | .apt_generated_tests/ 19 | .factorypath 20 | -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | asfMavenTlpStdBuild(jdks:[ "17", "21" ]) 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Apache Maven Archiver 2 | Copyright 2007-2024 The Apache Software Foundation 3 | 4 | This product includes software developed at 5 | The Apache Software Foundation (http://www.apache.org/). 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 17 | Contributing to [Apache Maven Archiver](https://maven.apache.org/shared/maven-archiver/) 18 | ====================== 19 | 20 | [![Apache License, Version 2.0, January 2004](https://img.shields.io/github/license/apache/maven.svg?label=License)][license] 21 | [![Maven Central](https://img.shields.io/maven-central/v/org.apache.maven/maven-archiver.svg?label=Maven%20Central)](https://search.maven.org/artifact/org.apache.maven/maven-archiver) 22 | [![Reproducible Builds](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/jvm-repo-rebuild/reproducible-central/master/content/org/apache/maven/shared/archiver/badge.json)](https://github.com/jvm-repo-rebuild/reproducible-central/blob/master/content/org/apache/maven/shared/archiver/README.md) 23 | [![Jenkins Status](https://img.shields.io/jenkins/s/https/ci-maven.apache.org/job/Maven/job/maven-box/job/maven-archiver/job/master.svg)][build] 24 | [![Jenkins tests](https://img.shields.io/jenkins/t/https/ci-maven.apache.org/job/Maven/job/maven-box/job/maven-archiver/job/master.svg)][test-results] 25 | 26 | 27 | You have found a bug, or you have an idea for a cool new feature? Contributing 28 | code is a great way to give something back to the open source community. Before 29 | you dig right into the code, there are a few guidelines that we need 30 | contributors to follow so that we can have a chance of keeping on top of 31 | things. 32 | 33 | Getting Started 34 | --------------- 35 | 36 | + Make sure you have a [GitHub account](https://github.com/signup/free). 37 | + If you're planning to implement a new feature, it makes sense to discuss your changes 38 | on the [dev list][ml-list] first. 39 | This way you can make sure you're not wasting your time on something that isn't 40 | considered to be in Apache Maven's scope. 41 | + Submit a ticket for your issue, assuming one does not already exist. 42 | + Clearly describe the issue, including steps to reproduce when it is a bug. 43 | + Make sure you fill in the earliest version that you know has the issue. 44 | + Fork the repository on GitHub. 45 | 46 | Making and Submitting Changes 47 | -------------- 48 | 49 | We accept Pull Requests via GitHub. The [developer mailing list][ml-list] is the 50 | main channel of communication for contributors. 51 | There are some guidelines which will make applying PRs easier for us: 52 | + Create a topic branch from where you want to base your work (this is usually the master branch). 53 | Push your changes to a topic branch in your fork of the repository. 54 | + Make commits of logical units. 55 | + Respect the original code style: by using the same [codestyle][code-style], 56 | patches should only highlight the actual difference, not being disturbed by any formatting issues: 57 | + Only use spaces for indentation. 58 | + Create minimal diffs - disable on save actions like reformat source code or organize imports. 59 | If you feel the source code should be reformatted, create a separate PR for this change. 60 | + Check for unnecessary whitespace with `git diff --check` before committing. 61 | + Make sure you have added the necessary tests (JUnit/IT) for your changes. 62 | + Run all the tests with `mvn -Prun-its verify` to assure nothing else was accidentally broken. 63 | + Submit a pull request to the repository in the Apache organization. 64 | 65 | If you plan to contribute on a regular basis, please consider filing a [contributor license agreement][cla]. 66 | 67 | Additional Resources 68 | -------------------- 69 | 70 | + [Contributing patches](https://maven.apache.org/guides/development/guide-maven-development.html#Creating_and_submitting_a_patch) 71 | + [Contributor License Agreement][cla] 72 | + [General GitHub documentation](https://help.github.com/) 73 | + [GitHub pull request documentation](https://help.github.com/send-pull-requests/) 74 | + [Apache Maven X Account](https://x.com/ASFMavenProject) 75 | + [Apache Maven Bluesky Account](https://bsky.app/profile/maven.apache.org) 76 | + [Apache Maven Mastodon Account](https://mastodon.social/deck/@ASFMavenProject@fosstodon.org) 77 | 78 | [license]: https://www.apache.org/licenses/LICENSE-2.0 79 | [ml-list]: https://maven.apache.org/mailing-lists.html 80 | [code-style]: https://maven.apache.org/developers/conventions/code.html 81 | [cla]: https://www.apache.org/licenses/#clas 82 | [maven-wiki]: https://cwiki.apache.org/confluence/display/MAVEN/Index 83 | [test-results]: https://ci-maven.apache.org/job/Maven/job/maven-box/job/maven-archiver/job/master/lastCompletedBuild/testReport/ 84 | [build]: https://ci-maven.apache.org/job/Maven/job/maven-box/job/maven-archiver/job/master/ 85 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 20 | 4.0.0 21 | 22 | 23 | org.apache.maven.shared 24 | maven-shared-components 25 | 43 26 | 27 | 28 | 29 | maven-archiver 30 | 4.0.0-beta-4-SNAPSHOT 31 | 32 | Apache Maven Archiver 33 | Provides utility methods for creating JARs and other archive files from a Maven project. 34 | 35 | 36 | scm:git:https://gitbox.apache.org/repos/asf/maven-archiver.git 37 | scm:git:https://gitbox.apache.org/repos/asf/maven-archiver.git 38 | maven-archiver-4.0.0-beta-2 39 | https://github.com/apache/maven-archiver/tree/${project.scm.tag} 40 | 41 | 42 | GitHub Issues 43 | https://github.com/apache/maven-archiver/issues 44 | 45 | 46 | Jenkins 47 | https://ci-maven.apache.org/job/Maven/job/maven-box/job/maven-archiver/ 48 | 49 | 50 | 51 | apache.website 52 | scm:svn:https://svn.apache.org/repos/asf/maven/website/components/${maven.site.path} 53 | 54 | 55 | 56 | 57 | 17 58 | 4.0.0-beta-5 59 | 60 | 3.27.3 61 | 4.0.0-beta-2 62 | 4.10.0 63 | 1.28 64 | 4.0.2 65 | 5.0.0 66 | 67 | 2024-11-27T16:58:36Z 68 | 69 | 70 | 71 | 74 | 75 | org.apache.maven 76 | maven-api-core 77 | ${mavenVersion} 78 | 79 | 80 | org.apache.maven 81 | maven-api-model 82 | ${mavenVersion} 83 | 84 | 85 | 88 | 89 | org.codehaus.plexus 90 | plexus-archiver 91 | ${plexusArchiverVersion} 92 | 93 | 94 | org.codehaus.plexus 95 | plexus-interpolation 96 | ${plexusInterpolationVersion} 97 | 98 | 99 | org.codehaus.plexus 100 | plexus-utils 101 | ${plexusUtilsVersion} 102 | 103 | 104 | 107 | 108 | org.apache.maven.plugin-testing 109 | maven-plugin-testing-harness 110 | ${mavenPluginTestingVersion} 111 | test 112 | 113 | 114 | org.apache.maven 115 | maven-api-impl 116 | ${mavenVersion} 117 | test 118 | 119 | 120 | org.junit.jupiter 121 | junit-jupiter-api 122 | ${versions.junit5} 123 | test 124 | 125 | 126 | org.junit.jupiter 127 | junit-jupiter-params 128 | ${versions.junit5} 129 | test 130 | 131 | 132 | org.assertj 133 | assertj-core 134 | ${assertjVersion} 135 | test 136 | 137 | 138 | org.mockito 139 | mockito-core 140 | ${mockitoVersion} 141 | test 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | org.apache.maven.plugins 150 | maven-surefire-plugin 151 | 152 | true 153 | 154 | 155 | 156 | org.apache.maven.plugins 157 | maven-dependency-plugin 158 | 159 | 160 | analyze 161 | 162 | analyze-only 163 | 164 | 165 | true 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | -------------------------------------------------------------------------------- /src/main/java/org/apache/maven/shared/archiver/ManifestConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package org.apache.maven.shared.archiver; 20 | 21 | /** 22 | * Capture common manifest configuration. 23 | */ 24 | // TODO Is this general enough to be in Plexus Archiver? 25 | public class ManifestConfiguration { 26 | /** 27 | * The simple layout. 28 | */ 29 | public static final String CLASSPATH_LAYOUT_TYPE_SIMPLE = "simple"; 30 | 31 | /** 32 | * The layout type 33 | */ 34 | public static final String CLASSPATH_LAYOUT_TYPE_REPOSITORY = "repository"; 35 | 36 | /** 37 | * custom layout type. 38 | */ 39 | public static final String CLASSPATH_LAYOUT_TYPE_CUSTOM = "custom"; 40 | 41 | private String mainClass; 42 | 43 | private String packageName; 44 | 45 | private boolean addClasspath; 46 | 47 | private boolean addExtensions; 48 | 49 | /** 50 | * This gets prefixed to all classpath entries. 51 | */ 52 | private String classpathPrefix = ""; 53 | 54 | /** 55 | * Add default, reproducible entries {@code Created-By} and {@code Build-Jdk-Spec}. 56 | * 57 | * @since 3.4.0 58 | */ 59 | private boolean addDefaultEntries = true; 60 | 61 | /** 62 | * Add build environment information about Maven, JDK, and OS. 63 | * 64 | * @since 3.4.0 65 | */ 66 | private boolean addBuildEnvironmentEntries; 67 | 68 | /** 69 | * Add default implementation entries if this is an extension specification. 70 | * 71 | * @since 2.1 72 | */ 73 | private boolean addDefaultSpecificationEntries; 74 | 75 | /** 76 | * Add default implementation entries if this is an extension. 77 | * 78 | * @since 2.1 79 | */ 80 | private boolean addDefaultImplementationEntries; 81 | 82 | private String classpathLayoutType = CLASSPATH_LAYOUT_TYPE_SIMPLE; 83 | 84 | private String customClasspathLayout; 85 | 86 | private boolean useUniqueVersions = true; 87 | 88 | /** 89 | *

Getter for the field mainClass.

90 | * 91 | * @return mainClass 92 | */ 93 | public String getMainClass() { 94 | return mainClass; 95 | } 96 | 97 | /** 98 | *

Getter for the field packageName.

99 | * 100 | * @return the package name. 101 | */ 102 | public String getPackageName() { 103 | return packageName; 104 | } 105 | 106 | /** 107 | *

isAddClasspath.

108 | * 109 | * @return if addClasspath true or false. 110 | */ 111 | public boolean isAddClasspath() { 112 | return addClasspath; 113 | } 114 | 115 | /** 116 | *

isAddDefaultEntries.

117 | * 118 | * @return {@link #addDefaultEntries} 119 | */ 120 | public boolean isAddDefaultEntries() { 121 | return addDefaultEntries; 122 | } 123 | 124 | /** 125 | *

isAddBuildEnvironmentEntries.

126 | * 127 | * @return {@link #addBuildEnvironmentEntries} 128 | */ 129 | public boolean isAddBuildEnvironmentEntries() { 130 | return addBuildEnvironmentEntries; 131 | } 132 | 133 | /** 134 | *

isAddDefaultImplementationEntries.

135 | * 136 | * @return {@link #addDefaultImplementationEntries} 137 | */ 138 | public boolean isAddDefaultImplementationEntries() { 139 | return addDefaultImplementationEntries; 140 | } 141 | 142 | /** 143 | *

isAddDefaultSpecificationEntries.

144 | * 145 | * @return {@link #addDefaultSpecificationEntries} 146 | */ 147 | public boolean isAddDefaultSpecificationEntries() { 148 | return addDefaultSpecificationEntries; 149 | } 150 | 151 | /** 152 | *

isAddExtensions.

153 | * 154 | * @return {@link #addExtensions} 155 | */ 156 | public boolean isAddExtensions() { 157 | return addExtensions; 158 | } 159 | 160 | /** 161 | *

Setter for the field addClasspath.

162 | * 163 | * @param addClasspath turn on addClasspath or off. 164 | */ 165 | public void setAddClasspath(boolean addClasspath) { 166 | this.addClasspath = addClasspath; 167 | } 168 | 169 | /** 170 | *

Setter for the field addDefaultEntries.

171 | * 172 | * @param addDefaultEntries add default entries true/false. 173 | */ 174 | public void setAddDefaultEntries(boolean addDefaultEntries) { 175 | this.addDefaultEntries = addDefaultEntries; 176 | } 177 | 178 | /** 179 | *

Setter for the field addBuildEnvironmentEntries.

180 | * 181 | * @param addBuildEnvironmentEntries add build environment information true/false. 182 | */ 183 | public void setAddBuildEnvironmentEntries(boolean addBuildEnvironmentEntries) { 184 | this.addBuildEnvironmentEntries = addBuildEnvironmentEntries; 185 | } 186 | 187 | /** 188 | *

Setter for the field addDefaultImplementationEntries.

189 | * 190 | * @param addDefaultImplementationEntries true to add default implementations false otherwise. 191 | */ 192 | public void setAddDefaultImplementationEntries(boolean addDefaultImplementationEntries) { 193 | this.addDefaultImplementationEntries = addDefaultImplementationEntries; 194 | } 195 | 196 | /** 197 | *

Setter for the field addDefaultSpecificationEntries.

198 | * 199 | * @param addDefaultSpecificationEntries add default specifications true/false. 200 | */ 201 | public void setAddDefaultSpecificationEntries(boolean addDefaultSpecificationEntries) { 202 | this.addDefaultSpecificationEntries = addDefaultSpecificationEntries; 203 | } 204 | 205 | /** 206 | *

Setter for the field addExtensions.

207 | * 208 | * @param addExtensions true to add extensions false otherwise. 209 | */ 210 | public void setAddExtensions(boolean addExtensions) { 211 | this.addExtensions = addExtensions; 212 | } 213 | 214 | /** 215 | *

Setter for the field classpathPrefix.

216 | * 217 | * @param classpathPrefix The prefix. 218 | */ 219 | public void setClasspathPrefix(String classpathPrefix) { 220 | this.classpathPrefix = classpathPrefix; 221 | } 222 | 223 | /** 224 | *

Setter for the field mainClass.

225 | * 226 | * @param mainClass The main class. 227 | */ 228 | public void setMainClass(String mainClass) { 229 | this.mainClass = mainClass; 230 | } 231 | 232 | /** 233 | *

Setter for the field packageName.

234 | * 235 | * @param packageName The package name. 236 | */ 237 | public void setPackageName(String packageName) { 238 | this.packageName = packageName; 239 | } 240 | 241 | /** 242 | *

Getter for the field classpathPrefix.

243 | * 244 | * @return The classpath prefix. 245 | */ 246 | public String getClasspathPrefix() { 247 | String cpp = classpathPrefix.replaceAll("\\\\", "/"); 248 | 249 | if (cpp.length() != 0 && !cpp.endsWith("/")) { 250 | cpp += "/"; 251 | } 252 | 253 | return cpp; 254 | } 255 | 256 | /** 257 | * Return the type of layout to use when formatting classpath entries. Default is taken from the constant 258 | * CLASSPATH_LAYOUT_TYPE_SIMPLE, declared in this class, which has a value of 'simple'. Other values are: 259 | * 'repository' (CLASSPATH_LAYOUT_TYPE_REPOSITORY, or the same as a maven classpath layout), and 'custom' 260 | * (CLASSPATH_LAYOUT_TYPE_CUSTOM).
261 | * NOTE: If you specify a type of 'custom' you MUST set 262 | * {@link ManifestConfiguration#setCustomClasspathLayout(String)}. 263 | * 264 | * @return The classpath layout type. 265 | */ 266 | public String getClasspathLayoutType() { 267 | return classpathLayoutType; 268 | } 269 | 270 | /** 271 | * Set the type of layout to use when formatting classpath entries. Should be one of: 'simple' 272 | * (CLASSPATH_LAYOUT_TYPE_SIMPLE), 'repository' (CLASSPATH_LAYOUT_TYPE_REPOSITORY, or the same as a maven classpath 273 | * layout), and 'custom' (CLASSPATH_LAYOUT_TYPE_CUSTOM). The constant names noted here are defined in the 274 | * {@link ManifestConfiguration} class.
275 | * NOTE: If you specify a type of 'custom' you MUST set 276 | * {@link ManifestConfiguration#setCustomClasspathLayout(String)}. 277 | * 278 | * @param classpathLayoutType The classpath layout type. 279 | */ 280 | public void setClasspathLayoutType(String classpathLayoutType) { 281 | this.classpathLayoutType = classpathLayoutType; 282 | } 283 | 284 | /** 285 | * Retrieve the layout expression for use when the layout type set in 286 | * {@link ManifestConfiguration#setClasspathLayoutType(String)} has the value 'custom'. 287 | * The default value is 288 | * null. Expressions will be evaluated against the following ordered list of classpath-related objects: 289 | *
    290 | *
  1. The current {@code Artifact} instance, if one exists.
  2. 291 | *
  3. The current {@code ArtifactHandler} instance from the artifact above.
  4. 292 | *
293 | *
294 | * NOTE: If you specify a layout type of 'custom' you MUST set this layout expression. 295 | * 296 | * @return The custom classpath layout. 297 | */ 298 | public String getCustomClasspathLayout() { 299 | return customClasspathLayout; 300 | } 301 | 302 | /** 303 | * Set the layout expression for use when the layout type set in 304 | * {@link ManifestConfiguration#setClasspathLayoutType(String)} has the value 'custom'. 305 | * Expressions will be 306 | * evaluated against the following ordered list of classpath-related objects: 307 | *
    308 | *
  1. The current {@code Artifact} instance, if one exists.
  2. 309 | *
  3. The current {@code ArtifactHandler} instance from the artifact above.
  4. 310 | *
311 | *
312 | * NOTE: If you specify a layout type of 'custom' you MUST set this layout expression. 313 | * You can take a look at 314 | *
    315 | *
  1. {@link MavenArchiver#SIMPLE_LAYOUT}
  2. 316 | *
  3. {@link MavenArchiver#SIMPLE_LAYOUT_NONUNIQUE}
  4. 317 | *
  5. {@link MavenArchiver#REPOSITORY_LAYOUT}
  6. 318 | *
  7. {@link MavenArchiver#REPOSITORY_LAYOUT_NONUNIQUE}
  8. 319 | *
320 | * how such an expression looks like. 321 | * 322 | * @param customClasspathLayout The custom classpath layout. 323 | */ 324 | public void setCustomClasspathLayout(String customClasspathLayout) { 325 | this.customClasspathLayout = customClasspathLayout; 326 | } 327 | 328 | /** 329 | * Retrieve the flag for whether snapshot artifacts should be added to the classpath using the 330 | * timestamp/buildnumber version (the default, when this flag is true), or using the generic 331 | * -SNAPSHOT version (when the flag is false).
332 | * NOTE: If the snapshot was installed locally, this flag will not have an effect on 333 | * that artifact's inclusion, since it will have the same version either way (i.e. -SNAPSHOT naming). 334 | * 335 | * @return The state of {@link #useUniqueVersions} 336 | */ 337 | public boolean isUseUniqueVersions() { 338 | return useUniqueVersions; 339 | } 340 | 341 | /** 342 | * Set the flag for whether snapshot artifacts should be added to the classpath using the timestamp/buildnumber 343 | * version (the default, when this flag is true), or using the generic -SNAPSHOT version (when the flag is false). 344 | *
345 | * NOTE: If the snapshot was installed locally, this flag will not have an effect on that artifact's 346 | * inclusion, since it will have the same version either way (i.e. -SNAPSHOT naming). 347 | * 348 | * @param useUniqueVersions true to use unique versions or not. 349 | */ 350 | public void setUseUniqueVersions(boolean useUniqueVersions) { 351 | this.useUniqueVersions = useUniqueVersions; 352 | } 353 | } 354 | -------------------------------------------------------------------------------- /src/main/java/org/apache/maven/shared/archiver/ManifestSection.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package org.apache.maven.shared.archiver; 20 | 21 | import java.util.LinkedHashMap; 22 | import java.util.Map; 23 | 24 | /** 25 | * ManifestSection class. 26 | */ 27 | public class ManifestSection { 28 | 29 | private String name = null; 30 | 31 | private final Map manifestEntries = new LinkedHashMap<>(); 32 | 33 | /** 34 | *

addManifestEntry.

35 | * 36 | * @param key The key of the manifest entry. 37 | * @param value The appropriate value. 38 | */ 39 | public void addManifestEntry(String key, String value) { 40 | manifestEntries.put(key, value); 41 | } 42 | 43 | /** 44 | *

Getter for the field manifestEntries.

45 | * 46 | * @return The entries. 47 | */ 48 | public Map getManifestEntries() { 49 | return manifestEntries; 50 | } 51 | 52 | /** 53 | *

Getter for the field name.

54 | * 55 | * @return The name. 56 | */ 57 | public String getName() { 58 | return name; 59 | } 60 | 61 | /** 62 | *

Setter for the field name.

63 | * 64 | * @param name the name. 65 | */ 66 | public void setName(String name) { 67 | this.name = name; 68 | } 69 | 70 | /** 71 | *

addManifestEntries.

72 | * 73 | * @param map The map to add. 74 | */ 75 | public void addManifestEntries(Map map) { 76 | manifestEntries.putAll(map); 77 | } 78 | 79 | /** 80 | *

isManifestEntriesEmpty.

81 | * 82 | * @return true if empty false otherwise. 83 | */ 84 | public boolean isManifestEntriesEmpty() { 85 | return manifestEntries.isEmpty(); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/org/apache/maven/shared/archiver/MavenArchiveConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package org.apache.maven.shared.archiver; 20 | 21 | import java.nio.file.Path; 22 | import java.util.LinkedHashMap; 23 | import java.util.LinkedList; 24 | import java.util.List; 25 | import java.util.Map; 26 | 27 | /** 28 | * Capture common archive configuration. 29 | * 30 | * @author Brett Porter 31 | */ 32 | // TODO Is this general enough to be in Plexus Archiver? 33 | public class MavenArchiveConfiguration { 34 | private boolean compress = true; 35 | 36 | private boolean recompressAddedZips = true; 37 | 38 | private boolean addMavenDescriptor = true; 39 | 40 | private Path manifestFile; 41 | 42 | // TODO: Rename this attribute to manifestConfiguration; 43 | private ManifestConfiguration manifest; 44 | 45 | private Map manifestEntries = new LinkedHashMap<>(); 46 | 47 | private List manifestSections = new LinkedList<>(); 48 | 49 | /** 50 | * @since 2.2 51 | */ 52 | private boolean forced = true; 53 | 54 | /** 55 | * @since 2.3 56 | */ 57 | private Path pomPropertiesFile; 58 | 59 | /** 60 | *

isCompress.

61 | * 62 | * @return {@link #compress} 63 | */ 64 | public boolean isCompress() { 65 | return compress; 66 | } 67 | 68 | /** 69 | *

isRecompressAddedZips.

70 | * 71 | * @return {@link #recompressAddedZips} 72 | */ 73 | public boolean isRecompressAddedZips() { 74 | return recompressAddedZips; 75 | } 76 | 77 | /** 78 | *

Setter for the field recompressAddedZips.

79 | * 80 | * @param recompressAddedZips {@link #recompressAddedZips} 81 | */ 82 | public void setRecompressAddedZips(boolean recompressAddedZips) { 83 | this.recompressAddedZips = recompressAddedZips; 84 | } 85 | 86 | /** 87 | *

isAddMavenDescriptor.

88 | * 89 | * @return {@link #addMavenDescriptor} 90 | */ 91 | public boolean isAddMavenDescriptor() { 92 | return addMavenDescriptor; 93 | } 94 | 95 | /** 96 | *

Getter for the field manifestFile.

97 | * 98 | * @return {@link #manifestFile} 99 | */ 100 | public Path getManifestFile() { 101 | return manifestFile; 102 | } 103 | 104 | /** 105 | *

Getter for the field manifest.

106 | * 107 | * @return {@link #manifest} 108 | */ 109 | // TODO: Change the name of this method into getManifestConfiguration() 110 | public ManifestConfiguration getManifest() { 111 | if (manifest == null) { 112 | manifest = new ManifestConfiguration(); 113 | } 114 | return manifest; 115 | } 116 | 117 | /** 118 | *

Setter for the field compress.

119 | * 120 | * @param compress set compress to true/false. 121 | */ 122 | public void setCompress(boolean compress) { 123 | this.compress = compress; 124 | } 125 | 126 | /** 127 | *

Setter for the field addMavenDescriptor.

128 | * 129 | * @param addMavenDescriptor activate to add maven descriptor or not. 130 | */ 131 | public void setAddMavenDescriptor(boolean addMavenDescriptor) { 132 | this.addMavenDescriptor = addMavenDescriptor; 133 | } 134 | 135 | /** 136 | *

Setter for the field manifestFile.

137 | * 138 | * @param manifestFile The manifest file. 139 | */ 140 | public void setManifestFile(Path manifestFile) { 141 | this.manifestFile = manifestFile; 142 | } 143 | 144 | /** 145 | *

Setter for the field manifest.

146 | * 147 | * @param manifest {@link ManifestConfiguration} 148 | */ 149 | public void setManifest(ManifestConfiguration manifest) { 150 | this.manifest = manifest; 151 | } 152 | 153 | /** 154 | *

addManifestEntry.

155 | * 156 | * @param key The key of the entry. 157 | * @param value The value of the entry. 158 | */ 159 | public void addManifestEntry(String key, String value) { 160 | manifestEntries.put(key, value); 161 | } 162 | 163 | /** 164 | *

addManifestEntries.

165 | * 166 | * @param map The whole map which should be added. 167 | */ 168 | public void addManifestEntries(Map map) { 169 | manifestEntries.putAll(map); 170 | } 171 | 172 | /** 173 | *

isManifestEntriesEmpty.

174 | * 175 | * @return are there entries true yes false otherwise. 176 | */ 177 | public boolean isManifestEntriesEmpty() { 178 | return manifestEntries.isEmpty(); 179 | } 180 | 181 | /** 182 | *

Getter for the field manifestEntries.

183 | * 184 | * @return {@link #manifestEntries} 185 | */ 186 | public Map getManifestEntries() { 187 | return manifestEntries; 188 | } 189 | 190 | /** 191 | *

Setter for the field manifestEntries.

192 | * 193 | * @param manifestEntries {@link #manifestEntries} 194 | */ 195 | public void setManifestEntries(Map manifestEntries) { 196 | this.manifestEntries = manifestEntries; 197 | } 198 | 199 | /** 200 | *

addManifestSection.

201 | * 202 | * @param section {@link ManifestSection} 203 | */ 204 | public void addManifestSection(ManifestSection section) { 205 | manifestSections.add(section); 206 | } 207 | 208 | /** 209 | *

addManifestSections.

210 | * 211 | * @param list Added list of {@link ManifestSection}. 212 | */ 213 | public void addManifestSections(List list) { 214 | manifestSections.addAll(list); 215 | } 216 | 217 | /** 218 | *

isManifestSectionsEmpty.

219 | * 220 | * @return if manifestSections is empty or not. 221 | */ 222 | public boolean isManifestSectionsEmpty() { 223 | return manifestSections.isEmpty(); 224 | } 225 | 226 | /** 227 | *

Getter for the field manifestSections.

228 | * 229 | * @return {@link #manifestSections} 230 | */ 231 | public List getManifestSections() { 232 | return manifestSections; 233 | } 234 | 235 | /** 236 | *

Setter for the field manifestSections.

237 | * 238 | * @param manifestSections set The list of {@link ManifestSection}. 239 | */ 240 | public void setManifestSections(List manifestSections) { 241 | this.manifestSections = manifestSections; 242 | } 243 | 244 | /** 245 | *

246 | * Returns, whether recreating the archive is forced (default). Setting this option to false means, that the 247 | * archiver should compare the timestamps of included files with the timestamp of the target archive and rebuild the 248 | * archive only, if the latter timestamp precedes the former timestamps. Checking for timestamps will typically 249 | * offer a performance gain (in particular, if the following steps in a build can be suppressed, if an archive isn't 250 | * recrated) on the cost that you get inaccurate results from time to time. In particular, removal of source files 251 | * won't be detected. 252 | *

253 | *

254 | * An archiver doesn't necessarily support checks for uptodate. If so, setting this option to true will simply be 255 | * ignored. 256 | *

257 | * 258 | * @return True, if the target archive should always be created; false otherwise 259 | * @see #setForced(boolean) 260 | */ 261 | public boolean isForced() { 262 | return forced; 263 | } 264 | 265 | /** 266 | *

267 | * Sets, whether recreating the archive is forced (default). Setting this option to false means, that the archiver 268 | * should compare the timestamps of included files with the timestamp of the target archive and rebuild the archive 269 | * only, if the latter timestamp precedes the former timestamps. Checking for timestamps will typically offer a 270 | * performance gain (in particular, if the following steps in a build can be suppressed, if an archive isn't 271 | * recrated) on the cost that you get inaccurate results from time to time. In particular, removal of source files 272 | * won't be detected. 273 | *

274 | *

275 | * An archiver doesn't necessarily support checks for uptodate. If so, setting this option to true will simply be 276 | * ignored. 277 | *

278 | * 279 | * @param forced True, if the target archive should always be created; false otherwise 280 | * @see #isForced() 281 | */ 282 | public void setForced(boolean forced) { 283 | this.forced = forced; 284 | } 285 | 286 | /** 287 | * Returns the location of the "pom.properties" file. May be null, in which case a default value is choosen. 288 | * 289 | * @return "pom.properties" location or null. 290 | */ 291 | public Path getPomPropertiesFile() { 292 | return pomPropertiesFile; 293 | } 294 | 295 | /** 296 | * Sets the location of the "pom.properties" file. May be null, in which case a default value is choosen. 297 | * 298 | * @param pomPropertiesFile "pom.properties" location or null. 299 | */ 300 | public void setPomPropertiesFile(Path pomPropertiesFile) { 301 | this.pomPropertiesFile = pomPropertiesFile; 302 | } 303 | } 304 | -------------------------------------------------------------------------------- /src/main/java/org/apache/maven/shared/archiver/MavenArchiver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package org.apache.maven.shared.archiver; 20 | 21 | import javax.lang.model.SourceVersion; 22 | 23 | import java.io.File; 24 | import java.io.IOException; 25 | import java.io.InputStream; 26 | import java.nio.file.Files; 27 | import java.nio.file.Path; 28 | import java.nio.file.Paths; 29 | import java.nio.file.attribute.FileTime; 30 | import java.time.Instant; 31 | import java.time.OffsetDateTime; 32 | import java.time.ZoneOffset; 33 | import java.time.format.DateTimeParseException; 34 | import java.time.temporal.ChronoUnit; 35 | import java.util.ArrayList; 36 | import java.util.Collections; 37 | import java.util.List; 38 | import java.util.Map; 39 | import java.util.Optional; 40 | import java.util.Properties; 41 | import java.util.jar.Attributes; 42 | import java.util.regex.Matcher; 43 | import java.util.regex.Pattern; 44 | 45 | import org.apache.maven.api.Dependency; 46 | import org.apache.maven.api.PathScope; 47 | import org.apache.maven.api.Project; 48 | import org.apache.maven.api.Session; 49 | import org.apache.maven.api.services.DependencyResolver; 50 | import org.apache.maven.api.services.DependencyResolverResult; 51 | import org.codehaus.plexus.archiver.jar.JarArchiver; 52 | import org.codehaus.plexus.archiver.jar.Manifest; 53 | import org.codehaus.plexus.archiver.jar.ManifestException; 54 | import org.codehaus.plexus.interpolation.InterpolationException; 55 | import org.codehaus.plexus.interpolation.Interpolator; 56 | import org.codehaus.plexus.interpolation.PrefixAwareRecursionInterceptor; 57 | import org.codehaus.plexus.interpolation.PrefixedObjectValueSource; 58 | import org.codehaus.plexus.interpolation.PrefixedPropertiesValueSource; 59 | import org.codehaus.plexus.interpolation.RecursionInterceptor; 60 | import org.codehaus.plexus.interpolation.StringSearchInterpolator; 61 | import org.codehaus.plexus.interpolation.ValueSource; 62 | 63 | import static org.apache.maven.shared.archiver.ManifestConfiguration.CLASSPATH_LAYOUT_TYPE_CUSTOM; 64 | import static org.apache.maven.shared.archiver.ManifestConfiguration.CLASSPATH_LAYOUT_TYPE_REPOSITORY; 65 | import static org.apache.maven.shared.archiver.ManifestConfiguration.CLASSPATH_LAYOUT_TYPE_SIMPLE; 66 | 67 | /** 68 | * MavenArchiver class. 69 | */ 70 | public class MavenArchiver { 71 | 72 | private static final String CREATED_BY = "Maven Archiver"; 73 | 74 | /** 75 | * The simple layout. 76 | */ 77 | public static final String SIMPLE_LAYOUT = 78 | "${artifact.artifactId}-${artifact.version}${dashClassifier?}.${artifact.extension}"; 79 | 80 | /** 81 | * Repository layout. 82 | */ 83 | public static final String REPOSITORY_LAYOUT = 84 | "${artifact.groupIdPath}/${artifact.artifactId}/" + "${artifact.baseVersion}/${artifact.artifactId}-" 85 | + "${artifact.version}${dashClassifier?}.${artifact.extension}"; 86 | 87 | /** 88 | * simple layout non unique. 89 | */ 90 | public static final String SIMPLE_LAYOUT_NONUNIQUE = 91 | "${artifact.artifactId}-${artifact.baseVersion}${dashClassifier?}.${artifact.extension}"; 92 | 93 | /** 94 | * Repository layout non unique. 95 | */ 96 | public static final String REPOSITORY_LAYOUT_NONUNIQUE = 97 | "${artifact.groupIdPath}/${artifact.artifactId}/" + "${artifact.baseVersion}/${artifact.artifactId}-" 98 | + "${artifact.baseVersion}${dashClassifier?}.${artifact.extension}"; 99 | 100 | private static final Instant DATE_MIN = Instant.parse("1980-01-01T00:00:02Z"); 101 | 102 | private static final Instant DATE_MAX = Instant.parse("2099-12-31T23:59:59Z"); 103 | 104 | private static final List ARTIFACT_EXPRESSION_PREFIXES; 105 | 106 | static { 107 | List artifactExpressionPrefixes = new ArrayList<>(); 108 | artifactExpressionPrefixes.add("artifact."); 109 | 110 | ARTIFACT_EXPRESSION_PREFIXES = artifactExpressionPrefixes; 111 | } 112 | 113 | static boolean isValidModuleName(String name) { 114 | return SourceVersion.isName(name); 115 | } 116 | 117 | private JarArchiver archiver; 118 | 119 | private File archiveFile; 120 | 121 | private String createdBy; 122 | 123 | private boolean buildJdkSpecDefaultEntry = true; 124 | 125 | /** 126 | *

getManifest.

127 | * 128 | * @param session the Maven Session 129 | * @param project the Maven Project 130 | * @param config the MavenArchiveConfiguration 131 | * @return the {@link org.codehaus.plexus.archiver.jar.Manifest} 132 | * @throws MavenArchiverException in case of a failure 133 | */ 134 | public Manifest getManifest(Session session, Project project, MavenArchiveConfiguration config) 135 | throws MavenArchiverException { 136 | boolean hasManifestEntries = !config.isManifestEntriesEmpty(); 137 | Map entries = hasManifestEntries ? config.getManifestEntries() : Collections.emptyMap(); 138 | 139 | Manifest manifest = getManifest(session, project, config.getManifest(), entries); 140 | 141 | try { 142 | // any custom manifest entries in the archive configuration manifest? 143 | if (hasManifestEntries) { 144 | 145 | for (Map.Entry entry : entries.entrySet()) { 146 | String key = entry.getKey(); 147 | String value = entry.getValue(); 148 | Manifest.Attribute attr = manifest.getMainSection().getAttribute(key); 149 | if (key.equals(Attributes.Name.CLASS_PATH.toString()) && attr != null) { 150 | // Merge the user-supplied Class-Path value with the programmatically 151 | // created Class-Path. Note that the user-supplied value goes first 152 | // so that resources there will override any in the standard Class-Path. 153 | attr.setValue(value + " " + attr.getValue()); 154 | } else { 155 | addManifestAttribute(manifest, key, value); 156 | } 157 | } 158 | } 159 | 160 | // any custom manifest sections in the archive configuration manifest? 161 | if (!config.isManifestSectionsEmpty()) { 162 | for (ManifestSection section : config.getManifestSections()) { 163 | Manifest.Section theSection = new Manifest.Section(); 164 | theSection.setName(section.getName()); 165 | 166 | if (!section.isManifestEntriesEmpty()) { 167 | Map sectionEntries = section.getManifestEntries(); 168 | 169 | for (Map.Entry entry : sectionEntries.entrySet()) { 170 | String key = entry.getKey(); 171 | String value = entry.getValue(); 172 | Manifest.Attribute attr = new Manifest.Attribute(key, value); 173 | theSection.addConfiguredAttribute(attr); 174 | } 175 | } 176 | 177 | manifest.addConfiguredSection(theSection); 178 | } 179 | } 180 | } catch (ManifestException e) { 181 | throw new MavenArchiverException("Unable to create manifest", e); 182 | } 183 | 184 | return manifest; 185 | } 186 | 187 | /** 188 | * Return a pre-configured manifest. 189 | * 190 | * @param project {@link org.apache.maven.api.Project} 191 | * @param config {@link ManifestConfiguration} 192 | * @return {@link org.codehaus.plexus.archiver.jar.Manifest} 193 | * @throws MavenArchiverException exception. 194 | */ 195 | // TODO Add user attributes list and user groups list 196 | public Manifest getManifest(Project project, ManifestConfiguration config) throws MavenArchiverException { 197 | return getManifest(null, project, config, Collections.emptyMap()); 198 | } 199 | 200 | public Manifest getManifest(Session session, Project project, ManifestConfiguration config) 201 | throws MavenArchiverException { 202 | return getManifest(session, project, config, Collections.emptyMap()); 203 | } 204 | 205 | private void addManifestAttribute(Manifest manifest, Map map, String key, String value) 206 | throws ManifestException { 207 | if (map.containsKey(key)) { 208 | return; // The map value will be added later 209 | } 210 | addManifestAttribute(manifest, key, value); 211 | } 212 | 213 | private void addManifestAttribute(Manifest manifest, String key, String value) throws ManifestException { 214 | if (!(value == null || value.isEmpty())) { 215 | Manifest.Attribute attr = new Manifest.Attribute(key, value); 216 | manifest.addConfiguredAttribute(attr); 217 | } else { 218 | // if the value is empty, create an entry with an empty string 219 | // to prevent null print in the manifest file 220 | Manifest.Attribute attr = new Manifest.Attribute(key, ""); 221 | manifest.addConfiguredAttribute(attr); 222 | } 223 | } 224 | 225 | /** 226 | *

getManifest.

227 | * 228 | * @param session {@link org.apache.maven.api.Session} 229 | * @param project {@link org.apache.maven.api.Project} 230 | * @param config {@link ManifestConfiguration} 231 | * @param entries The entries. 232 | * @return {@link org.codehaus.plexus.archiver.jar.Manifest} 233 | * @throws MavenArchiverException exception 234 | */ 235 | protected Manifest getManifest( 236 | Session session, Project project, ManifestConfiguration config, Map entries) 237 | throws MavenArchiverException { 238 | try { 239 | return doGetManifest(session, project, config, entries); 240 | } catch (ManifestException e) { 241 | throw new MavenArchiverException("Unable to create manifest", e); 242 | } 243 | } 244 | 245 | protected Manifest doGetManifest( 246 | Session session, Project project, ManifestConfiguration config, Map entries) 247 | throws ManifestException { 248 | // TODO: Should we replace "map" with a copy? Note, that we modify it! 249 | Manifest m = new Manifest(); 250 | 251 | if (config.isAddDefaultEntries()) { 252 | handleDefaultEntries(m, entries); 253 | } 254 | 255 | if (config.isAddBuildEnvironmentEntries()) { 256 | handleBuildEnvironmentEntries(session, m, entries); 257 | } 258 | 259 | DependencyResolverResult result; 260 | if (config.isAddClasspath() || config.isAddExtensions()) { 261 | result = session.getService(DependencyResolver.class).resolve(session, project, PathScope.MAIN_RUNTIME); 262 | } else { 263 | result = null; 264 | } 265 | 266 | if (config.isAddClasspath()) { 267 | StringBuilder classpath = new StringBuilder(); 268 | 269 | String classpathPrefix = config.getClasspathPrefix(); 270 | String layoutType = config.getClasspathLayoutType(); 271 | String layout = config.getCustomClasspathLayout(); 272 | 273 | Interpolator interpolator = new StringSearchInterpolator(); 274 | 275 | for (Map.Entry entry : result.getDependencies().entrySet()) { 276 | Path artifactFile = entry.getValue(); 277 | Dependency dependency = entry.getKey(); 278 | if (Files.isRegularFile(artifactFile.toAbsolutePath())) { 279 | if (!classpath.isEmpty()) { 280 | classpath.append(" "); 281 | } 282 | classpath.append(classpathPrefix); 283 | 284 | // NOTE: If the artifact or layout type (from config) is null, give up and use the file name by 285 | // itself. 286 | if (dependency == null || layoutType == null) { 287 | classpath.append(artifactFile.getFileName().toString()); 288 | } else { 289 | List valueSources = new ArrayList<>(); 290 | 291 | handleExtraExpression(dependency, valueSources); 292 | 293 | for (ValueSource vs : valueSources) { 294 | interpolator.addValueSource(vs); 295 | } 296 | 297 | RecursionInterceptor recursionInterceptor = 298 | new PrefixAwareRecursionInterceptor(ARTIFACT_EXPRESSION_PREFIXES); 299 | 300 | try { 301 | switch (layoutType) { 302 | case CLASSPATH_LAYOUT_TYPE_SIMPLE: 303 | if (config.isUseUniqueVersions()) { 304 | classpath.append(interpolator.interpolate(SIMPLE_LAYOUT, recursionInterceptor)); 305 | } else { 306 | classpath.append(interpolator.interpolate( 307 | SIMPLE_LAYOUT_NONUNIQUE, recursionInterceptor)); 308 | } 309 | break; 310 | case CLASSPATH_LAYOUT_TYPE_REPOSITORY: 311 | // we use layout /$groupId[0]/../${groupId[n]/$artifactId/$version/{fileName} 312 | // here we must find the Artifact in the project Artifacts 313 | // to create the maven layout 314 | if (config.isUseUniqueVersions()) { 315 | classpath.append( 316 | interpolator.interpolate(REPOSITORY_LAYOUT, recursionInterceptor)); 317 | } else { 318 | classpath.append(interpolator.interpolate( 319 | REPOSITORY_LAYOUT_NONUNIQUE, recursionInterceptor)); 320 | } 321 | break; 322 | case CLASSPATH_LAYOUT_TYPE_CUSTOM: 323 | if (layout == null) { 324 | throw new ManifestException(CLASSPATH_LAYOUT_TYPE_CUSTOM 325 | + " layout type was declared, but custom layout expression was not" 326 | + " specified. Check your " 327 | + " element."); 328 | } 329 | 330 | classpath.append(interpolator.interpolate(layout, recursionInterceptor)); 331 | break; 332 | default: 333 | throw new ManifestException("Unknown classpath layout type: '" + layoutType 334 | + "'. Check your element."); 335 | } 336 | } catch (InterpolationException e) { 337 | ManifestException error = new ManifestException( 338 | "Error interpolating artifact path for classpath entry: " + e.getMessage()); 339 | 340 | error.initCause(e); 341 | throw error; 342 | } finally { 343 | for (ValueSource vs : valueSources) { 344 | interpolator.removeValuesSource(vs); 345 | } 346 | } 347 | } 348 | } 349 | } 350 | 351 | if (!classpath.isEmpty()) { 352 | // Class-Path is special and should be added to manifest even if 353 | // it is specified in the manifestEntries section 354 | addManifestAttribute(m, "Class-Path", classpath.toString()); 355 | } 356 | } 357 | 358 | if (config.isAddDefaultSpecificationEntries()) { 359 | handleSpecificationEntries(project, entries, m); 360 | } 361 | 362 | if (config.isAddDefaultImplementationEntries()) { 363 | handleImplementationEntries(project, entries, m); 364 | } 365 | 366 | String mainClass = config.getMainClass(); 367 | if (mainClass != null && !mainClass.isEmpty()) { 368 | addManifestAttribute(m, entries, "Main-Class", mainClass); 369 | } 370 | 371 | addCustomEntries(m, entries, config); 372 | 373 | return m; 374 | } 375 | 376 | private void handleExtraExpression(Dependency dependency, List valueSources) { 377 | valueSources.add(new PrefixedObjectValueSource(ARTIFACT_EXPRESSION_PREFIXES, dependency, true)); 378 | valueSources.add(new PrefixedObjectValueSource(ARTIFACT_EXPRESSION_PREFIXES, dependency.getType(), true)); 379 | 380 | Properties extraExpressions = new Properties(); 381 | // FIXME: This query method SHOULD NOT affect the internal 382 | // state of the artifact version, but it does. 383 | if (!dependency.isSnapshot()) { 384 | extraExpressions.setProperty("baseVersion", dependency.getVersion().toString()); 385 | } 386 | 387 | extraExpressions.setProperty("groupIdPath", dependency.getGroupId().replace('.', '/')); 388 | String classifier = dependency.getClassifier(); 389 | if (classifier != null && !classifier.isEmpty()) { 390 | extraExpressions.setProperty("dashClassifier", "-" + classifier); 391 | extraExpressions.setProperty("dashClassifier?", "-" + classifier); 392 | } else { 393 | extraExpressions.setProperty("dashClassifier", ""); 394 | extraExpressions.setProperty("dashClassifier?", ""); 395 | } 396 | valueSources.add(new PrefixedPropertiesValueSource(ARTIFACT_EXPRESSION_PREFIXES, extraExpressions, true)); 397 | } 398 | 399 | private void handleImplementationEntries(Project project, Map entries, Manifest m) 400 | throws ManifestException { 401 | addManifestAttribute( 402 | m, entries, "Implementation-Title", project.getModel().getName()); 403 | addManifestAttribute(m, entries, "Implementation-Version", project.getVersion()); 404 | 405 | if (project.getModel().getOrganization() != null) { 406 | addManifestAttribute( 407 | m, 408 | entries, 409 | "Implementation-Vendor", 410 | project.getModel().getOrganization().getName()); 411 | } 412 | } 413 | 414 | private void handleSpecificationEntries(Project project, Map entries, Manifest m) 415 | throws ManifestException { 416 | addManifestAttribute( 417 | m, entries, "Specification-Title", project.getModel().getName()); 418 | 419 | String version = project.getPomArtifact().getVersion().toString(); 420 | Matcher matcher = Pattern.compile("([0-9]+\\.[0-9]+)(.*?)").matcher(version); 421 | if (matcher.matches()) { 422 | String specVersion = matcher.group(1); 423 | addManifestAttribute(m, entries, "Specification-Version", specVersion); 424 | } 425 | /* 426 | TODO: v4: overconstrained 427 | try { 428 | Version version = project.getArtifact().getVersion(); 429 | String specVersion = String.format("%s.%s", version.getMajorVersion(), version.getMinorVersion()); 430 | addManifestAttribute(m, entries, "Specification-Version", specVersion); 431 | } catch (OverConstrainedVersionException e) { 432 | throw new ManifestException("Failed to get selected artifact version to calculate" 433 | + " the specification version: " + e.getMessage()); 434 | } 435 | */ 436 | 437 | if (project.getModel().getOrganization() != null) { 438 | addManifestAttribute( 439 | m, 440 | entries, 441 | "Specification-Vendor", 442 | project.getModel().getOrganization().getName()); 443 | } 444 | } 445 | 446 | private void addCustomEntries(Manifest m, Map entries, ManifestConfiguration config) 447 | throws ManifestException { 448 | /* 449 | * TODO: rethink this, it wasn't working Artifact projectArtifact = project.getArtifact(); if ( 450 | * projectArtifact.isSnapshot() ) { Manifest.Attribute buildNumberAttr = new Manifest.Attribute( "Build-Number", 451 | * "" + project.getSnapshotDeploymentBuildNumber() ); m.addConfiguredAttribute( buildNumberAttr ); } 452 | */ 453 | if (config.getPackageName() != null) { 454 | addManifestAttribute(m, entries, "Package", config.getPackageName()); 455 | } 456 | } 457 | 458 | /** 459 | *

Getter for the field archiver.

460 | * 461 | * @return {@link org.codehaus.plexus.archiver.jar.JarArchiver} 462 | */ 463 | public JarArchiver getArchiver() { 464 | return archiver; 465 | } 466 | 467 | /** 468 | *

Setter for the field archiver.

469 | * 470 | * @param archiver {@link org.codehaus.plexus.archiver.jar.JarArchiver} 471 | */ 472 | public void setArchiver(JarArchiver archiver) { 473 | this.archiver = archiver; 474 | } 475 | 476 | /** 477 | *

setOutputFile.

478 | * 479 | * @param outputFile Set output file. 480 | */ 481 | public void setOutputFile(File outputFile) { 482 | archiveFile = outputFile; 483 | } 484 | 485 | /** 486 | *

createArchive.

487 | * 488 | * @param session {@link org.apache.maven.api.Session} 489 | * @param project {@link org.apache.maven.api.Project} 490 | * @param archiveConfiguration {@link MavenArchiveConfiguration} 491 | * @throws MavenArchiverException Archiver Exception. 492 | */ 493 | public void createArchive(Session session, Project project, MavenArchiveConfiguration archiveConfiguration) 494 | throws MavenArchiverException { 495 | try { 496 | doCreateArchive(session, project, archiveConfiguration); 497 | } catch (ManifestException | IOException e) { 498 | throw new MavenArchiverException(e); 499 | } 500 | } 501 | 502 | public void doCreateArchive(Session session, Project project, MavenArchiveConfiguration archiveConfiguration) 503 | throws ManifestException, IOException { 504 | // we have to clone the project instance so we can write out the pom with the deployment version, 505 | // without impacting the main project instance... 506 | boolean forced = archiveConfiguration.isForced(); 507 | if (archiveConfiguration.isAddMavenDescriptor()) { 508 | // ---------------------------------------------------------------------- 509 | // We want to add the metadata for the project to the JAR in two forms: 510 | // 511 | // The first form is that of the POM itself. Applications that wish to 512 | // access the POM for an artifact using maven tools they can. 513 | // 514 | // The second form is that of a properties file containing the basic 515 | // top-level POM elements so that applications that wish to access 516 | // POM information without the use of maven tools can do so. 517 | // ---------------------------------------------------------------------- 518 | 519 | String groupId = project.getGroupId(); 520 | 521 | String artifactId = project.getArtifactId(); 522 | 523 | String version; 524 | if (project.getPomArtifact().isSnapshot()) { 525 | version = project.getPomArtifact().getVersion().toString(); 526 | } else { 527 | version = project.getVersion(); 528 | } 529 | 530 | archiver.addFile( 531 | project.getPomPath().toFile(), "META-INF/maven/" + groupId + "/" + artifactId + "/pom.xml"); 532 | 533 | // ---------------------------------------------------------------------- 534 | // Create pom.properties file 535 | // ---------------------------------------------------------------------- 536 | 537 | Path customPomPropertiesFile = archiveConfiguration.getPomPropertiesFile(); 538 | Path dir = Paths.get(project.getBuild().getDirectory(), "maven-archiver"); 539 | Path pomPropertiesFile = dir.resolve("pom.properties"); 540 | 541 | new PomPropertiesUtil() 542 | .createPomProperties( 543 | groupId, artifactId, version, archiver, customPomPropertiesFile, pomPropertiesFile); 544 | } 545 | 546 | // ---------------------------------------------------------------------- 547 | // Create the manifest 548 | // ---------------------------------------------------------------------- 549 | 550 | archiver.setMinimalDefaultManifest(true); 551 | Path manifestFile = archiveConfiguration.getManifestFile(); 552 | if (manifestFile != null) { 553 | archiver.setManifest(manifestFile.toFile()); 554 | } 555 | Manifest manifest = getManifest(session, project, archiveConfiguration); 556 | // Configure the jar 557 | archiver.addConfiguredManifest(manifest); 558 | archiver.setCompress(archiveConfiguration.isCompress()); 559 | archiver.setRecompressAddedZips(archiveConfiguration.isRecompressAddedZips()); 560 | archiver.setDestFile(archiveFile); 561 | archiver.setForced(forced); 562 | if (!archiveConfiguration.isForced() && archiver.isSupportingForced()) { 563 | // TODO Should issue a warning here, but how do we get a logger? 564 | // TODO getLog().warn( 565 | // "Forced build is disabled, but disabling the forced mode isn't supported by the archiver." ); 566 | } 567 | String automaticModuleName = manifest.getMainSection().getAttributeValue("Automatic-Module-Name"); 568 | if (automaticModuleName != null) { 569 | if (!isValidModuleName(automaticModuleName)) { 570 | throw new ManifestException("Invalid automatic module name: '" + automaticModuleName + "'"); 571 | } 572 | } 573 | 574 | // create archive 575 | archiver.createArchive(); 576 | } 577 | 578 | private void handleDefaultEntries(Manifest m, Map entries) throws ManifestException { 579 | String createdBy = this.createdBy; 580 | if (createdBy == null) { 581 | createdBy = createdBy(CREATED_BY, "org.apache.maven", "maven-archiver"); 582 | } 583 | addManifestAttribute(m, entries, "Created-By", createdBy); 584 | if (buildJdkSpecDefaultEntry) { 585 | addManifestAttribute(m, entries, "Build-Jdk-Spec", System.getProperty("java.specification.version")); 586 | } 587 | } 588 | 589 | private void handleBuildEnvironmentEntries(Session session, Manifest m, Map entries) 590 | throws ManifestException { 591 | addManifestAttribute( 592 | m, 593 | entries, 594 | "Build-Tool", 595 | session != null ? session.getSystemProperties().get("maven.build.version") : "Apache Maven"); 596 | addManifestAttribute( 597 | m, 598 | entries, 599 | "Build-Jdk", 600 | String.format("%s (%s)", System.getProperty("java.version"), System.getProperty("java.vendor"))); 601 | addManifestAttribute( 602 | m, 603 | entries, 604 | "Build-Os", 605 | String.format( 606 | "%s (%s; %s)", 607 | System.getProperty("os.name"), 608 | System.getProperty("os.version"), 609 | System.getProperty("os.arch"))); 610 | } 611 | 612 | private static String getCreatedByVersion(String groupId, String artifactId) { 613 | final Properties properties = loadOptionalProperties(MavenArchiver.class.getResourceAsStream( 614 | "/META-INF/maven/" + groupId + "/" + artifactId + "/pom.properties")); 615 | 616 | return properties.getProperty("version"); 617 | } 618 | 619 | private static Properties loadOptionalProperties(final InputStream inputStream) { 620 | Properties properties = new Properties(); 621 | if (inputStream != null) { 622 | try (InputStream in = inputStream) { 623 | properties.load(in); 624 | } catch (IllegalArgumentException | IOException ex) { 625 | // ignore and return empty properties 626 | } 627 | } 628 | return properties; 629 | } 630 | 631 | /** 632 | * Define a value for "Created By" entry. 633 | * 634 | * @param description description of the plugin, like "Maven Source Plugin" 635 | * @param groupId groupId where to get version in pom.properties 636 | * @param artifactId artifactId where to get version in pom.properties 637 | * @since 3.5.0 638 | */ 639 | public void setCreatedBy(String description, String groupId, String artifactId) { 640 | createdBy = createdBy(description, groupId, artifactId); 641 | } 642 | 643 | private String createdBy(String description, String groupId, String artifactId) { 644 | String createdBy = description; 645 | String version = getCreatedByVersion(groupId, artifactId); 646 | if (version != null) { 647 | createdBy += " " + version; 648 | } 649 | return createdBy; 650 | } 651 | 652 | /** 653 | * Add "Build-Jdk-Spec" entry as part of default manifest entries (true by default). 654 | * For plugins whose output is not impacted by JDK release (like maven-source-plugin), adding 655 | * Jdk spec adds unnecessary requirement on JDK version used at build to get reproducible result. 656 | * 657 | * @param buildJdkSpecDefaultEntry the value for "Build-Jdk-Spec" entry 658 | * @since 3.5.0 659 | */ 660 | public void setBuildJdkSpecDefaultEntry(boolean buildJdkSpecDefaultEntry) { 661 | this.buildJdkSpecDefaultEntry = buildJdkSpecDefaultEntry; 662 | } 663 | 664 | /** 665 | * Parse output timestamp configured for Reproducible Builds' archive entries. 666 | * 667 | *

Either as {@link java.time.format.DateTimeFormatter#ISO_OFFSET_DATE_TIME} or as a number representing seconds 668 | * since the epoch (like SOURCE_DATE_EPOCH). 669 | * 670 | * @param outputTimestamp the value of {@code ${project.build.outputTimestamp}} (may be {@code null}) 671 | * @return the parsed timestamp as an {@code Optional}, {@code empty} if input is {@code null} or input 672 | * contains only 1 character (not a number) 673 | * @since 3.6.0 674 | * @throws IllegalArgumentException if the outputTimestamp is neither ISO 8601 nor an integer, or it's not within 675 | * the valid range 1980-01-01T00:00:02Z to 2099-12-31T23:59:59Z as defined by 676 | * ZIP application note, 677 | * section 4.4.6. 678 | */ 679 | public static Optional parseBuildOutputTimestamp(String outputTimestamp) { 680 | // Fail-fast on nulls 681 | if (outputTimestamp == null) { 682 | return Optional.empty(); 683 | } 684 | 685 | // Number representing seconds since the epoch 686 | if (isNumeric(outputTimestamp)) { 687 | final Instant date = Instant.ofEpochSecond(Long.parseLong(outputTimestamp)); 688 | 689 | if (date.isBefore(DATE_MIN) || date.isAfter(DATE_MAX)) { 690 | throw new IllegalArgumentException( 691 | "'" + date + "' is not within the valid range " + DATE_MIN + " to " + DATE_MAX); 692 | } 693 | return Optional.of(date); 694 | } 695 | 696 | // no timestamp configured (1 character configuration is useful to override a full value during pom 697 | // inheritance) 698 | if (outputTimestamp.length() < 2) { 699 | return Optional.empty(); 700 | } 701 | 702 | try { 703 | // Parse the date in UTC such as '2011-12-03T10:15:30Z' or with an offset '2019-10-05T20:37:42+06:00'. 704 | final Instant date = OffsetDateTime.parse(outputTimestamp) 705 | .withOffsetSameInstant(ZoneOffset.UTC) 706 | .truncatedTo(ChronoUnit.SECONDS) 707 | .toInstant(); 708 | 709 | if (date.isBefore(DATE_MIN) || date.isAfter(DATE_MAX)) { 710 | throw new IllegalArgumentException( 711 | "'" + date + "' is not within the valid range " + DATE_MIN + " to " + DATE_MAX); 712 | } 713 | return Optional.of(date); 714 | } catch (DateTimeParseException pe) { 715 | throw new IllegalArgumentException( 716 | "Invalid project.build.outputTimestamp value '" + outputTimestamp + "'", pe); 717 | } 718 | } 719 | 720 | private static boolean isNumeric(String str) { 721 | 722 | if (str.isEmpty()) { 723 | return false; 724 | } 725 | 726 | for (char c : str.toCharArray()) { 727 | if (!Character.isDigit(c)) { 728 | return false; 729 | } 730 | } 731 | 732 | return true; 733 | } 734 | 735 | /** 736 | * Configure Reproducible Builds archive creation if a timestamp is provided. 737 | * 738 | * @param outputTimestamp the value of {@code project.build.outputTimestamp} (may be {@code null}) 739 | * @since 3.6.0 740 | * @see #parseBuildOutputTimestamp(String) 741 | */ 742 | public void configureReproducibleBuild(String outputTimestamp) { 743 | parseBuildOutputTimestamp(outputTimestamp).map(FileTime::from).ifPresent(modifiedTime -> getArchiver() 744 | .configureReproducibleBuild(modifiedTime)); 745 | } 746 | } 747 | -------------------------------------------------------------------------------- /src/main/java/org/apache/maven/shared/archiver/MavenArchiverException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package org.apache.maven.shared.archiver; 20 | 21 | import org.apache.maven.api.services.MavenException; 22 | 23 | public class MavenArchiverException extends MavenException { 24 | public MavenArchiverException() {} 25 | 26 | public MavenArchiverException(String message) { 27 | super(message); 28 | } 29 | 30 | public MavenArchiverException(String message, Throwable cause) { 31 | super(message, cause); 32 | } 33 | 34 | public MavenArchiverException(Throwable cause) { 35 | super(cause); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/org/apache/maven/shared/archiver/PomPropertiesUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package org.apache.maven.shared.archiver; 20 | 21 | import java.io.ByteArrayOutputStream; 22 | import java.io.IOException; 23 | import java.io.InputStream; 24 | import java.io.Writer; 25 | import java.nio.charset.StandardCharsets; 26 | import java.nio.file.Files; 27 | import java.nio.file.Path; 28 | import java.util.Properties; 29 | import java.util.stream.Collectors; 30 | 31 | import org.apache.maven.api.Project; 32 | import org.codehaus.plexus.archiver.Archiver; 33 | import org.codehaus.plexus.util.io.CachingWriter; 34 | 35 | /** 36 | * This class is responsible for creating the pom.properties file 37 | * in META-INF/maven/${groupId}/${artifactId}. 38 | * 39 | * @author slachiewicz 40 | * @version $Id: $Id 41 | */ 42 | public class PomPropertiesUtil { 43 | private Properties loadPropertiesFile(Path file) throws IOException { 44 | Properties fileProps = new Properties(); 45 | try (InputStream istream = Files.newInputStream(file)) { 46 | fileProps.load(istream); 47 | return fileProps; 48 | } 49 | } 50 | 51 | private void createPropertiesFile(Properties properties, Path outputFile) throws IOException { 52 | Path outputDir = outputFile.getParent(); 53 | if (outputDir != null) { 54 | Files.createDirectories(outputDir); 55 | } 56 | // For reproducible builds, sort the properties and drop comments. 57 | // The java.util.Properties class doesn't guarantee order so we have 58 | // to write the file using a Writer. 59 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); 60 | properties.store(baos, null); 61 | // The encoding can be either UTF-8 or ISO-8859-1, as any non ascii character 62 | // is transformed into a \\uxxxx sequence anyway 63 | String output = baos.toString(StandardCharsets.ISO_8859_1) 64 | .lines() 65 | .filter(line -> !line.startsWith("#")) 66 | .sorted() 67 | .collect(Collectors.joining("\n", "", "\n")); // system independent new line 68 | try (Writer writer = new CachingWriter(outputFile, StandardCharsets.ISO_8859_1)) { 69 | writer.write(output); 70 | } 71 | } 72 | 73 | /** 74 | * Creates the pom.properties file. 75 | * 76 | * @param project {@link org.apache.maven.api.Project} 77 | * @param archiver {@link org.codehaus.plexus.archiver.Archiver} 78 | * @param customPomPropertiesFile optional custom pom properties file 79 | * @param pomPropertiesFile The pom properties file. 80 | * @throws org.codehaus.plexus.archiver.ArchiverException archiver exception. 81 | * @throws java.io.IOException IO exception. 82 | */ 83 | public void createPomProperties( 84 | Project project, Archiver archiver, Path customPomPropertiesFile, Path pomPropertiesFile) 85 | throws IOException { 86 | final String groupId = project.getGroupId(); 87 | final String artifactId = project.getArtifactId(); 88 | final String version = project.getVersion(); 89 | createPomProperties(groupId, artifactId, version, archiver, customPomPropertiesFile, pomPropertiesFile); 90 | } 91 | 92 | public void createPomProperties( 93 | String groupId, 94 | String artifactId, 95 | String version, 96 | Archiver archiver, 97 | Path customPomPropertiesFile, 98 | Path pomPropertiesFile) 99 | throws IOException { 100 | Properties p; 101 | 102 | if (customPomPropertiesFile != null) { 103 | p = loadPropertiesFile(customPomPropertiesFile); 104 | } else { 105 | p = new Properties(); 106 | } 107 | 108 | p.setProperty("groupId", groupId); 109 | 110 | p.setProperty("artifactId", artifactId); 111 | 112 | p.setProperty("version", version); 113 | 114 | createPropertiesFile(p, pomPropertiesFile); 115 | 116 | archiver.addFile( 117 | pomPropertiesFile.toFile(), "META-INF/maven/" + groupId + "/" + artifactId + "/pom.properties"); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /src/site/apt/examples/classpath.apt: -------------------------------------------------------------------------------- 1 | ------ 2 | Set Up The Classpath 3 | ------ 4 | Dennis Lundberg 5 | ------ 6 | 2008-01-01 7 | ------ 8 | 9 | ~~ Licensed to the Apache Software Foundation (ASF) under one 10 | ~~ or more contributor license agreements. See the NOTICE file 11 | ~~ distributed with this work for additional information 12 | ~~ regarding copyright ownership. The ASF licenses this file 13 | ~~ to you under the Apache License, Version 2.0 (the 14 | ~~ "License"); you may not use this file except in compliance 15 | ~~ with the License. You may obtain a copy of the License at 16 | ~~ 17 | ~~ http://www.apache.org/licenses/LICENSE-2.0 18 | ~~ 19 | ~~ Unless required by applicable law or agreed to in writing, 20 | ~~ software distributed under the License is distributed on an 21 | ~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 22 | ~~ KIND, either express or implied. See the License for the 23 | ~~ specific language governing permissions and limitations 24 | ~~ under the License. 25 | 26 | Set Up The Classpath 27 | 28 | * {Contents} 29 | 30 | * {{{Add}Add A Class-Path Entry To The Manifest}} 31 | 32 | * {{{Make}Make The Jar Executable}} 33 | 34 | * {{{Prefix}Altering The Classpath: Defining a Classpath Directory Prefix}} 35 | 36 | * {{{Repository}Altering The Classpath: Using a Maven Repository-Style Classpath}} 37 | 38 | * {{{Custom}Altering The Classpath: Using a Custom Classpath Format}} 39 | 40 | * {{{Snapshot}Handling Snapshot Versions}} 41 | 42 | [] 43 | 44 | * {Add} A Class-Path Entry To The Manifest 45 | 46 | \[{{{Contents}Top}}\] 47 | 48 | Maven Archiver can add the classpath of your project to the manifest. This is 49 | done with the <<<\>>> configuration element. 50 | 51 | +-----+ 52 | 53 | ... 54 | 55 | 56 | 57 | org.apache.maven.plugins 58 | maven-jar-plugin 59 | ... 60 | 61 | 62 | 63 | true 64 | 65 | 66 | 67 | ... 68 | 69 | 70 | 71 | ... 72 | 73 | 74 | commons-lang 75 | commons-lang 76 | 2.1 77 | 78 | 79 | org.codehaus.plexus 80 | plexus-utils 81 | 1.1 82 | 83 | 84 | ... 85 | 86 | +-----+ 87 | 88 | The manifest produced using the above configuration would look like this: 89 | 90 | +-----+ 91 | Manifest-Version: 1.0 92 | Created-By: Apache Maven ${maven.version} 93 | Build-Jdk: ${java.version} 94 | Class-Path: plexus-utils-1.1.jar commons-lang-2.1.jar 95 | +-----+ 96 | 97 | 98 | * {Make} The Jar Executable 99 | 100 | \[{{{Contents}Top}}\] 101 | 102 | If you want to create an executable jar file, you need to configure Maven 103 | Archiver accordingly. You need to tell it which main class to use. This is 104 | done with the <<<\>>> configuration element. Here is a sample 105 | <<>> configured to add the classpath and use the class 106 | <<>> as the main class: 107 | 108 | +-----+ 109 | 110 | ... 111 | 112 | 113 | 114 | org.apache.maven.plugins 115 | maven-jar-plugin 116 | ... 117 | 118 | 119 | 120 | true 121 | fully.qualified.MainClass 122 | 123 | 124 | 125 | ... 126 | 127 | 128 | 129 | ... 130 | 131 | 132 | commons-lang 133 | commons-lang 134 | 2.1 135 | 136 | 137 | org.codehaus.plexus 138 | plexus-utils 139 | 1.1 140 | 141 | 142 | ... 143 | 144 | +-----+ 145 | 146 | The manifest produced using the above configuration would look like this: 147 | 148 | +-----+ 149 | Manifest-Version: 1.0 150 | Created-By: Apache Maven ${maven.version} 151 | Build-Jdk: ${java.version} 152 | Main-Class: fully.qualified.MainClass 153 | Class-Path: plexus-utils-1.1.jar commons-lang-2.1.jar 154 | +-----+ 155 | 156 | 157 | * Altering The Classpath: Defining a Classpath Directory {Prefix} 158 | 159 | \[{{{Contents}Top}}\] 160 | 161 | Sometimes it is useful to be able to alter the classpath, for example when 162 | {{{/plugins/maven-war-plugin/examples/skinny-wars.html}creating skinny war-files}}. 163 | This can be achieved with the <<<\>>> configuration element. 164 | 165 | +-----+ 166 | 167 | ... 168 | 169 | 170 | 171 | maven-war-plugin 172 | 173 | 174 | 175 | true 176 | lib/ 177 | 178 | 179 | 180 | 181 | 182 | 183 | ... 184 | 185 | 186 | commons-lang 187 | commons-lang 188 | 2.1 189 | 190 | 191 | org.codehaus.plexus 192 | plexus-utils 193 | 1.1 194 | 195 | 196 | ... 197 | 198 | +-----+ 199 | 200 | The manifest classpath produced using the above configuration would look like this: 201 | 202 | +-----+ 203 | Class-Path: lib/plexus-utils-1.1.jar lib/commons-lang-2.1.jar 204 | +-----+ 205 | 206 | * Altering The Classpath: Using a Maven {Repository}-Style Classpath 207 | 208 | \[{{{Contents}Top}}\] 209 | 210 | <(Since: 2.3, see below)> 211 | 212 | Occasionally, you may want to include a Maven repository-style directory structure in your 213 | archive. If you wish to reference the dependency archives within those directories in your 214 | manifest classpath, try using the <<<\>>> element with a value of 215 | <<<'repository'>>>, like this: 216 | 217 | +-----+ 218 | 219 | ... 220 | 221 | 222 | 223 | maven-jar-plugin 224 | 2.3 225 | 226 | 227 | 228 | true 229 | lib/ 230 | repository 231 | 232 | 233 | 234 | 235 | 236 | 237 | ... 238 | 239 | 240 | commons-lang 241 | commons-lang 242 | 2.1 243 | 244 | 245 | org.codehaus.plexus 246 | plexus-utils 247 | 1.1 248 | 249 | 250 | ... 251 | 252 | +-----+ 253 | 254 | The manifest classpath produced using the above configuration would look like this: 255 | 256 | +-----+ 257 | Class-Path: lib/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.jar lib/commons-lang/commons-lang/2.1/commons-lang-2.1.jar 258 | +-----+ 259 | 260 | * Altering The Classpath: Using a {Custom} Classpath Format 261 | 262 | \[{{{Contents}Top}}\] 263 | 264 | <(Since: 2.4)> 265 | 266 | At times, you may have dependency archives in a custom format within your own archive, one that doesn't 267 | conform to any of the above classpath layouts. If you wish to define a custom layout for dependency archives 268 | within your archive's manifest classpath, try using the <<<\>>> element with a value of 269 | <<<'custom'>>>, along with the <<<\>>> element, like this: 270 | 271 | +-----+ 272 | 273 | ... 274 | 275 | 276 | 277 | maven-war-plugin 278 | 279 | 280 | 281 | true 282 | custom 283 | WEB-INF/lib/$${artifact.groupIdPath}/$${artifact.artifactId}-$${artifact.version}$${dashClassifier?}.$${artifact.extension} 284 | 285 | 286 | 287 | 288 | 289 | 290 | ... 291 | 292 | 293 | commons-lang 294 | commons-lang 295 | 2.1 296 | 297 | 298 | org.codehaus.plexus 299 | plexus-utils 300 | 1.1 301 | 302 | 303 | ... 304 | 305 | +-----+ 306 | 307 | This classpath layout is a little more involved than the previous examples. 308 | To understand how the value of the <<<\>>> configuration 309 | is interpreted, it's useful to understand the rules applied when resolving 310 | expressions within the value: 311 | 312 | [[1]] If present, trim off the prefix 'artifact.' from the expression. 313 | 314 | [[2]] Attempt to resolve the expression as a reference to the Artifact using 315 | reflection (eg. <<<'artifactId'>>> becomes a reference to the method 316 | <<<'getArtifactId()'>>>). 317 | 318 | [[3]] Attempt to resolve the expression as a reference to the ArtifactHandler of 319 | the current Artifact, again using reflection (eg. <<<'extension'>>> becomes a reference 320 | to the method <<<'getExtension()'>>>). 321 | 322 | [[4]] Attempt to resolve the expression as a key in the special-case Properties instance, 323 | which contains the following mappings: 324 | 325 | * <<<'dashClassifier'>>>: If the Artifact has a classifier, this will be 326 | <<<'-${artifact.classifier}'>>>, otherwise this 327 | is an empty string. 328 | 329 | * <<<'dashClassifier?'>>>: This is a synonym of <<<'dashClassifier'>>>. 330 | 331 | * <<<'groupIdPath'>>>: This is the equivalent of <<<'${artifact.groupId}'>>>, 332 | with all <<<'.'>>> characters replaced by <<<'/'>>>. 333 | 334 | [] 335 | 336 | [] 337 | 338 | The manifest classpath produced using the above configuration would look like this: 339 | 340 | +-----+ 341 | Class-Path: WEB-INF/lib/org/codehaus/plexus/plexus-utils-1.1.jar WEB-INF/lib/commons-lang/commons-lang-2.1.jar 342 | +-----+ 343 | 344 | 345 | * Handling {Snapshot} Versions 346 | 347 | \[{{{Contents}Top}}\] 348 | 349 | <(Since 2.4)> 350 | 351 | Depending on how you construct your archive, you may have the ability to specify whether 352 | snapshot dependency archives are included with the version suffix <<<'-SNAPSHOT'>>>, or 353 | whether the unique timestamp and build-number for that archive is used. For instance, 354 | the {{{/plugins/maven-assembly-plugin}Assembly Plugin}} allows 355 | you to make this decision in the <<<\>>> element of its 356 | <<<\>>> descriptor section. 357 | 358 | ** Forcing the use of -SNAPSHOT versions when using the simple (default) or repository classpath layout 359 | 360 | To force the use of <<<'-SNAPSHOT'>>> version naming, simply disable the <<<\>>> 361 | configuration element, like this: 362 | 363 | +-----+ 364 | false 365 | +-----+ 366 | 367 | ** Forcing the use of -SNAPSHOT versions with custom layouts 368 | 369 | To force the use of <<<'-SNAPSHOT'>>> version naming, simply replace <<<'${artifact.version}'>>> 370 | with <<<'${artifact.baseVersion}'>>> in the custom layout example above, so it looks like this: 371 | 372 | +-----+ 373 | WEB-INF/lib/${artifact.groupIdPath}/${artifact.artifactId}-${artifact.baseVersion}${dashClassifier?}.${artifact.extension} 374 | +-----+ 375 | 376 | The full example configuration would look like this: 377 | 378 | +-----+ 379 | 380 | ... 381 | 382 | 383 | 384 | maven-war-plugin 385 | 386 | 387 | 388 | true 389 | custom 390 | WEB-INF/lib/${artifact.groupIdPath}/${artifact.artifactId}-${artifact.version}${dashClassifier?}.${artifact.extension} 391 | 392 | 393 | 394 | 395 | 396 | 397 | ... 398 | 399 | +-----+ 400 | -------------------------------------------------------------------------------- /src/site/apt/examples/manifest.apt: -------------------------------------------------------------------------------- 1 | ------ 2 | Manifest 3 | ------ 4 | Dennis Lundberg 5 | ------ 6 | 2008-01-01 7 | ------ 8 | 9 | ~~ Licensed to the Apache Software Foundation (ASF) under one 10 | ~~ or more contributor license agreements. See the NOTICE file 11 | ~~ distributed with this work for additional information 12 | ~~ regarding copyright ownership. The ASF licenses this file 13 | ~~ to you under the Apache License, Version 2.0 (the 14 | ~~ "License"); you may not use this file except in compliance 15 | ~~ with the License. You may obtain a copy of the License at 16 | ~~ 17 | ~~ http://www.apache.org/licenses/LICENSE-2.0 18 | ~~ 19 | ~~ Unless required by applicable law or agreed to in writing, 20 | ~~ software distributed under the License is distributed on an 21 | ~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 22 | ~~ KIND, either express or implied. See the License for the 23 | ~~ specific language governing permissions and limitations 24 | ~~ under the License. 25 | 26 | Manifest 27 | 28 | * Default Manifest 29 | 30 | The default manifest created by Maven Archiver will contain the following 31 | bits of information: 32 | 33 | +-----+ 34 | Manifest-Version: 1.0 35 | Created-By: Apache Maven ${maven.version} 36 | Build-Jdk: ${java.version} 37 | +-----+ 38 | 39 | <> The <<>> does not take toolchains configuration into account. It is the same 40 | JDK version as running the Maven instance. 41 | 42 | * Adding Implementation And Specification Details 43 | 44 | Starting with version 2.1, Maven Archiver no longer creates the 45 | Implementation and Specification details in the manifest by default. 46 | If you want them in your manifest you have to say so explicitly in your configuration. 47 | 48 | <> Because this is a recent change in Maven Archiver, different plugins 49 | may or may not have started using it yet. Please check the documentation for 50 | the plugin you want to use. In this example we use maven-jar-plugin 2.1 which 51 | was the first version of that plugin to use this new feature. 52 | 53 | +-----+ 54 | 55 | ... 56 | 57 | 58 | 59 | org.apache.maven.plugins 60 | maven-jar-plugin 61 | 2.1 62 | ... 63 | 64 | 65 | 66 | true 67 | true 68 | 69 | 70 | 71 | ... 72 | 73 | 74 | 75 | ... 76 | 77 | +-----+ 78 | 79 | The resulting manifest would contain these pieces of information: 80 | 81 | +-----+ 82 | Manifest-Version: 1.0 83 | Created-By: Apache Maven ${maven.version} 84 | Build-Jdk: ${java.version} 85 | Specification-Title: ${project.name} 86 | Specification-Version: ${project.artifact.selectedVersion.majorVersion}.${project.artifact.selectedVersion.minorVersion} 87 | Specification-Vendor: ${project.organization.name} 88 | Implementation-Title: ${project.name} 89 | Implementation-Version: ${project.version} 90 | Implementation-Vendor: ${project.organization.name} 91 | +-----+ 92 | 93 | <> If your pom.xml does not have an <<<\>>>/<<<\>>> 94 | element, then the <<>> and <<>> 95 | entries will <> be in the manifest. 96 | -------------------------------------------------------------------------------- /src/site/apt/examples/manifestEntries.apt: -------------------------------------------------------------------------------- 1 | ------ 2 | Manifest Entries 3 | ------ 4 | Dennis Lundberg 5 | ------ 6 | 2008-01-01 7 | ------ 8 | 9 | ~~ Licensed to the Apache Software Foundation (ASF) under one 10 | ~~ or more contributor license agreements. See the NOTICE file 11 | ~~ distributed with this work for additional information 12 | ~~ regarding copyright ownership. The ASF licenses this file 13 | ~~ to you under the Apache License, Version 2.0 (the 14 | ~~ "License"); you may not use this file except in compliance 15 | ~~ with the License. You may obtain a copy of the License at 16 | ~~ 17 | ~~ http://www.apache.org/licenses/LICENSE-2.0 18 | ~~ 19 | ~~ Unless required by applicable law or agreed to in writing, 20 | ~~ software distributed under the License is distributed on an 21 | ~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 22 | ~~ KIND, either express or implied. See the License for the 23 | ~~ specific language governing permissions and limitations 24 | ~~ under the License. 25 | 26 | Manifest Entries 27 | 28 | If you find that the other configuration options for Maven Archiver are not 29 | enough for manipulating the manifest, you can add your own entries to it. 30 | This is done with the <<<\>>> configuration element. 31 | 32 | In this example we'll add some entries to the manifest by specifying what we'd 33 | like in the <<<\>>>/<<<\>>> element of 34 | maven-jar-plugin. 35 | 36 | <> As with all the examples here, this configuration can be used in all 37 | plugins that use Maven Archiver, not just maven-jar-plugin as in this example. 38 | 39 | +-----+ 40 | 41 | http://some.url.org/ 42 | ... 43 | 44 | 45 | 46 | org.apache.maven.plugins 47 | maven-jar-plugin 48 | ... 49 | 50 | 51 | 52 | development 53 | ${project.url} 54 | 55 | 56 | 57 | ... 58 | 59 | 60 | 61 | ... 62 | 63 | +-----+ 64 | 65 | As you see above you can use literal values or you can have values from the 66 | POM interpolated into literals or simply use straight POM expressions. So this 67 | is what your resultant manifest will look like inside the created jar: 68 | 69 | +-----+ 70 | Manifest-Version: 1.0 71 | Created-By: Apache Maven ${maven.version} 72 | Build-Jdk: ${java.version} 73 | mode: development 74 | url: http://some.url.org/ 75 | +-----+ 76 | 77 | <> If your pom.xml does not have the <<<\>>> element, referenced 78 | through interpolation, then the entry <<>> will <> be in the 79 | manifest. 80 | -------------------------------------------------------------------------------- /src/site/apt/examples/manifestFile.apt: -------------------------------------------------------------------------------- 1 | ------ 2 | Use Your Own Manifest File 3 | ------ 4 | Dennis Lundberg 5 | ------ 6 | 2008-01-01 7 | ------ 8 | 9 | ~~ Licensed to the Apache Software Foundation (ASF) under one 10 | ~~ or more contributor license agreements. See the NOTICE file 11 | ~~ distributed with this work for additional information 12 | ~~ regarding copyright ownership. The ASF licenses this file 13 | ~~ to you under the Apache License, Version 2.0 (the 14 | ~~ "License"); you may not use this file except in compliance 15 | ~~ with the License. You may obtain a copy of the License at 16 | ~~ 17 | ~~ http://www.apache.org/licenses/LICENSE-2.0 18 | ~~ 19 | ~~ Unless required by applicable law or agreed to in writing, 20 | ~~ software distributed under the License is distributed on an 21 | ~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 22 | ~~ KIND, either express or implied. See the License for the 23 | ~~ specific language governing permissions and limitations 24 | ~~ under the License. 25 | 26 | Use Your Own Manifest File 27 | 28 | By default, Maven Archiver creates the manifest file for you. It is 29 | sometimes useful to use your own hand crafted manifest file. Say that you 30 | want to use the manifest file <<>>. 31 | This is done with the <<<\>>> configuration element by setting 32 | the value to the location of your file. 33 | 34 | The content of your own manifest file will be merged with the entries 35 | created by Maven Archiver. If you specify an entry in your own manifest file 36 | it will override the value created by Maven Archiver. 37 | 38 | <> As with all the examples here, this configuration can be used in all 39 | plugins that use Maven Archiver, not just maven-jar-plugin as in this example. 40 | 41 | +-----+ 42 | 43 | ... 44 | 45 | 46 | 47 | org.apache.maven.plugins 48 | maven-jar-plugin 49 | ... 50 | 51 | 52 | src/main/resources/META-INF/MANIFEST.MF 53 | 54 | 55 | ... 56 | 57 | 58 | 59 | ... 60 | 61 | +-----+ 62 | -------------------------------------------------------------------------------- /src/site/apt/examples/manifestSections.apt: -------------------------------------------------------------------------------- 1 | ------ 2 | Manifest Sections 3 | ------ 4 | Olivier Lamy 5 | Dennis Lundberg 6 | ------ 7 | 2008-01-01 8 | ------ 9 | 10 | ~~ Licensed to the Apache Software Foundation (ASF) under one 11 | ~~ or more contributor license agreements. See the NOTICE file 12 | ~~ distributed with this work for additional information 13 | ~~ regarding copyright ownership. The ASF licenses this file 14 | ~~ to you under the Apache License, Version 2.0 (the 15 | ~~ "License"); you may not use this file except in compliance 16 | ~~ with the License. You may obtain a copy of the License at 17 | ~~ 18 | ~~ http://www.apache.org/licenses/LICENSE-2.0 19 | ~~ 20 | ~~ Unless required by applicable law or agreed to in writing, 21 | ~~ software distributed under the License is distributed on an 22 | ~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 23 | ~~ KIND, either express or implied. See the License for the 24 | ~~ specific language governing permissions and limitations 25 | ~~ under the License. 26 | 27 | Manifest Sections 28 | 29 | The <<<\>>> element provides a way to add custom manifest 30 | sections. It contains a list of 31 | <<<\<{{{../index.html#class_manifestSection}manifestSection}}\>>>> elements. 32 | 33 | <> As with all the examples here, this configuration can be used in all 34 | plugins that use Maven Archiver, not just maven-jar-plugin as in this example. 35 | 36 | Given this configuration: 37 | 38 | +-----+ 39 | 40 | ... 41 | 42 | 43 | 44 | org.apache.maven.plugins 45 | maven-jar-plugin 46 | ... 47 | 48 | 49 | 50 | 51 | foo 52 | 53 | nice foo 54 | 55 | 56 | 57 | bar 58 | 59 | nice bar 60 | 61 | 62 | 63 | 64 | 65 | ... 66 | 67 | 68 | 69 | ... 70 | 71 | +-----+ 72 | 73 | The following content will end up in the manifest: 74 | 75 | +-----+ 76 | Manifest-Version: 1.0 77 | Created-By: Apache Maven ${maven.version} 78 | Build-Jdk: ${java.version} 79 | 80 | Name: foo 81 | id: nice foo 82 | 83 | Name: bar 84 | id: nice bar 85 | +-----+ 86 | -------------------------------------------------------------------------------- /src/site/resources/download.cgi: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # 20 | # Just call the standard mirrors.cgi script. It will use download.html 21 | # as the input template. 22 | exec /www/www.apache.org/dyn/mirrors/mirrors.cgi $* -------------------------------------------------------------------------------- /src/site/site.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 21 | 22 | 24 | 25 | org.apache.maven.skins 26 | maven-fluido-skin 27 | 1.9 28 | 29 | 30 |

31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /src/site/xdoc/download.xml.vm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 21 | 22 | 23 | 24 | Download ${project.name} Source 25 | 26 | 27 | 28 |
29 | 30 |

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

31 | 32 |

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

33 | 34 |

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

35 | 36 |

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

37 | 38 | 39 | 40 |

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

41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 |
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
60 | 61 |

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

65 | 66 |
67 | 68 | 69 |

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

70 |

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

71 |
72 |
73 | 74 |
75 | 76 | -------------------------------------------------------------------------------- /src/site/xdoc/index.xml.vm: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | Reference 23 | Olivier Lamy 24 | Dennis Lundberg 25 | 26 | 27 |
28 |

29 | The Maven Archiver is mainly used by plugins to handle packaging. The 30 | version numbers referenced in the Since column on this page are the 31 | version of the Maven Archiver component - not for any specific plugin. 32 | To see which version of Maven Archiver a plugin uses, go to the site 33 | for that plugin. 34 |

35 | 36 | 37 | <archive> 38 | <addMavenDescriptor/> 39 | <compress/> 40 | <forced/> 41 | <index/> 42 | <pomPropertiesFile/> 43 | 44 | <manifestFile/> 45 | <manifest> 46 | <addClasspath/> 47 | <addDefaultEntries/> 48 | <addDefaultImplementationEntries/> 49 | <addDefaultSpecificationEntries/> 50 | <addBuildEnvironmentEntries/> 51 | <addExtensions/> 52 | <classpathLayoutType/> 53 | <classpathPrefix/> 54 | <customClasspathLayout/> 55 | <mainClass/> 56 | <packageName/> 57 | <useUniqueVersions/> 58 | </manifest> 59 | <manifestEntries> 60 | <key>value</key> 61 | </manifestEntries> 62 | <manifestSections> 63 | <manifestSection> 64 | <name/> 65 | <manifestEntries> 66 | <key>value</key> 67 | </manifestEntries> 68 | <manifestSection/> 69 | </manifestSections> 70 | </archive> 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 98 | 99 | 100 | 101 | 102 | 103 | 107 | 108 | 109 | 110 | 111 | 112 | 128 | 129 | 130 | 131 | 132 | 133 | 143 | 144 | 145 | 146 | 147 | 148 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 |
ElementDescriptionTypeSince
addMavenDescriptor 85 | Whether the created archive will contain these two Maven files: 86 |
    87 |
  • 88 | The pom file, located in the archive in 89 | META-INF/maven/${groupId}/${artifactId}/pom.xml 90 |
  • 91 |
  • 92 | A pom.properties file, 93 | located in the archive in META-INF/maven/${groupId}/${artifactId}/pom.properties 94 |
  • 95 |
96 | The default value is true. 97 |
boolean
compress 104 | Activate compression for the archive. 105 | The default value is true. 106 | boolean
forced 113 | Whether recreating the archive is forced (default) or not. Setting 114 | this option to false, means that the archiver should compare the 115 | timestamps of included files with the timestamp of the target archive 116 | and rebuild the archive, only if the latter timestamp precedes the 117 | former timestamps. Checking for timestamps will typically offer a 118 | performance gain (in particular, if the following steps in a build 119 | can be suppressed, if an archive isn't recreated) on the cost that 120 | you get inaccurate results from time to time. In particular, removal 121 | of source files won't be detected. 122 |

123 | An archiver doesn't necessarily support checks for uptodate. If 124 | so, setting this option to true will simply be ignored. 125 |

126 | The default value is true. 127 |
boolean2.2
index 134 | Deprecated: See JDK-8305597 135 |

136 | Whether the created archive will contain an 137 | INDEX.LIST file. 138 |

139 |

140 | The default value is false. 141 |

142 |
boolean
pomPropertiesFile 149 | Use this to override the auto created 150 | pom.properties file 151 | (only if addMavenDescriptor is set to true) 152 | File2.3
manifestFileWith this you can supply your own manifest file.File
manifest
manifestEntriesA list of key/value pairs to add to the manifest.Map
manifestSections
181 |
182 | 183 |
184 | 185 |

186 | The auto created pom.properties file will contain the 187 | following content: 188 |

189 | 190 | artifactId=\${project.artifactId} 191 | groupId=\${project.groupId} 192 | version=\${project.version} 193 |
194 | 195 |
196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 210 | 211 | 212 | 213 | 214 | 215 | 224 | 225 | 226 | 227 | 228 | 229 | 237 | 238 | 239 | 240 | 241 | 242 | 250 | 251 | 252 | 253 | 254 | 255 | 263 | 264 | 265 | 266 | 267 | 268 | 273 | 274 | 275 | 276 | 277 | 278 | 288 | 289 | 290 | 291 | 292 | 293 | 298 | 299 | 300 | 301 | 302 | 303 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 336 | 337 | 338 | 339 |
ElementDescriptionTypeSince
addClasspath 207 | Whether to create a Class-Path manifest entry. 208 | The default value is false. 209 | boolean
addDefaultEntries 216 | If the manifest will contain these entries: 217 | 218 | Created-By: Maven Archiver ${maven-archiver.version} 219 | Build-Jdk-Spec: ${java.specification.version} 220 | Since 3.5.0, the default value of Created-By entry can be overridden using 221 | MavenArchiver.setCreatedBy(...) API.
222 | The default value is true. 223 |
boolean3.4.0
addDefaultImplementationEntries 230 | If the manifest will contain these entries: 231 | 232 | Implementation-Title: \${project.name} 233 | Implementation-Version: \${project.version} 234 | Implementation-Vendor: \${project.organization.name} 235 | The default value is false. 236 | boolean2.1 and 2.6
addDefaultSpecificationEntries 243 | If the manifest will contain these entries: 244 | 245 | Specification-Title: \${project.name} 246 | Specification-Version: \${project.artifact.selectedVersion.majorVersion}.\${project.artifact.selectedVersion.minorVersion} 247 | Specification-Vendor: \${project.organization.name} 248 | The default value is false. 249 | boolean2.1
addBuildEnvironmentEntries 256 | If the manifest will contain these entries: 257 | 258 | Build-Tool: ${maven.build.version} 259 | Build-Jdk: ${java.version} (${java.vendor}) 260 | Build-Os: ${os.name} (${os.version}; (${os.arch}) 261 | The default value is false. 262 | boolean3.4.0
addExtensions 269 | Whether to create an Extension-List manifest 270 | entry. 271 | The default value is false. 272 | boolean
classpathLayoutType 279 | The type of layout to use when formatting entries in the created 280 | Class-Path. Valid values are: simple, 281 | repository (the same as a Maven classpath layout) and 282 | custom. 283 |
284 | Note: If you specify a type of custom you 285 | must also set customClasspathLayout. 286 | The default value is simple. 287 |
String2.4
classpathPrefix 294 | A text that will be prefixed to all your Class-Path 295 | entries. 296 | The default value is "". 297 | String
customClasspathLayout 304 | The layout expression to use when the layout type set in 305 | classpathLayoutType has the value custom. 306 | Expressions will be evaluated against the following ordered list 307 | of classpath-related objects: 308 |
    309 |
  1. The current Artifact instance, if one exists.
  2. 310 |
  3. The current ArtifactHandler instance from the artifact above.
  4. 311 |
312 | Note: If you specify a layout type of custom 313 | you must set this layout expression. 314 |
String2.4
mainClassThe Main-Class manifest entry.String
packageNamePackage manifest entry.String
useUniqueVersions 333 | Whether to use unique timestamp Snapshot versions rather than -SNAPSHOT versions. 334 | The default value is true. 335 | boolean2.4
340 |
341 | 342 |
343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 |
ElementDescriptionTypeSince
name 354 | The name of the section. 355 | String
manifestEntriesA list of key/value pairs to add to the manifest.Map
366 |
367 |
368 | 369 |
370 | -------------------------------------------------------------------------------- /src/test/java/org/apache/maven/shared/archiver/ManifestConfigurationTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package org.apache.maven.shared.archiver; 20 | 21 | import org.junit.jupiter.api.BeforeEach; 22 | import org.junit.jupiter.api.Test; 23 | 24 | import static org.assertj.core.api.Assertions.assertThat; 25 | 26 | class ManifestConfigurationTest { 27 | 28 | private ManifestConfiguration manifestConfiguration; 29 | 30 | @BeforeEach 31 | void before() { 32 | this.manifestConfiguration = new ManifestConfiguration(); 33 | } 34 | 35 | @Test 36 | void XXX() { 37 | assertThat(manifestConfiguration.getClasspathLayoutType()) 38 | .isEqualTo(ManifestConfiguration.CLASSPATH_LAYOUT_TYPE_SIMPLE); 39 | } 40 | 41 | @Test 42 | void getClasspathPrefixShouldReturnPrefixWithSlashesInsteadOfBackSlashes() { 43 | manifestConfiguration.setClasspathPrefix("\\lib\\const\\"); 44 | assertThat(manifestConfiguration.getClasspathPrefix()).isEqualTo("/lib/const/"); 45 | } 46 | 47 | @Test 48 | void getClasspathPrefixShouldReturnPrefixWithTraingSlash() { 49 | manifestConfiguration.setClasspathPrefix("const"); 50 | assertThat(manifestConfiguration.getClasspathPrefix()).isEqualTo("const/"); 51 | } 52 | 53 | @Test 54 | void getClasspathPrefixShouldReturnTheTrailingSlash() { 55 | manifestConfiguration.setClasspathPrefix("const/"); 56 | assertThat(manifestConfiguration.getClasspathPrefix()).isEqualTo("const/"); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/test/java/org/apache/maven/shared/archiver/MavenArchiveConfigurationTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package org.apache.maven.shared.archiver; 20 | 21 | import java.util.Map; 22 | 23 | import org.junit.jupiter.api.BeforeEach; 24 | import org.junit.jupiter.api.Test; 25 | 26 | import static org.assertj.core.api.Assertions.assertThat; 27 | import static org.assertj.core.api.Assertions.entry; 28 | 29 | /** 30 | * @author Karl Heinz Marbaise khmarbaise@apache.org. 31 | */ 32 | class MavenArchiveConfigurationTest { 33 | 34 | private MavenArchiveConfiguration archive; 35 | 36 | @BeforeEach 37 | void before() { 38 | archive = new MavenArchiveConfiguration(); 39 | archive.setManifest(new ManifestConfiguration()); 40 | archive.setForced(false); 41 | archive.setCompress(false); 42 | } 43 | 44 | @Test 45 | void addingSingleEntryShouldBeReturned() { 46 | archive.addManifestEntry("key1", "value1"); 47 | Map manifestEntries = archive.getManifestEntries(); 48 | assertThat(manifestEntries).containsExactly(entry("key1", "value1")); 49 | } 50 | 51 | @Test 52 | void addingTwoEntriesShouldBeReturnedInInsertOrder() { 53 | archive.addManifestEntry("key1", "value1"); 54 | archive.addManifestEntry("key2", "value2"); 55 | Map manifestEntries = archive.getManifestEntries(); 56 | assertThat(manifestEntries).containsExactly(entry("key1", "value1"), entry("key2", "value2")); 57 | } 58 | 59 | @Test 60 | void addingThreeEntriesShouldBeReturnedInInsertOrder() { 61 | archive.addManifestEntry("key1", "value1"); 62 | archive.addManifestEntry("key2", "value2"); 63 | archive.addManifestEntry("key3", "value3"); 64 | Map manifestEntries = archive.getManifestEntries(); 65 | assertThat(manifestEntries) 66 | .containsExactly(entry("key1", "value1"), entry("key2", "value2"), entry("key3", "value3")); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/test/java/org/apache/maven/shared/archiver/PomPropertiesUtilTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package org.apache.maven.shared.archiver; 20 | 21 | import java.io.IOException; 22 | import java.io.Writer; 23 | import java.nio.charset.StandardCharsets; 24 | import java.nio.file.Files; 25 | import java.nio.file.Path; 26 | import java.util.List; 27 | import java.util.Properties; 28 | 29 | import org.codehaus.plexus.archiver.jar.JarArchiver; 30 | import org.junit.jupiter.api.Test; 31 | import org.junit.jupiter.api.io.TempDir; 32 | 33 | import static org.assertj.core.api.Assertions.assertThat; 34 | import static org.junit.jupiter.api.Assertions.assertEquals; 35 | 36 | class PomPropertiesUtilTest { 37 | 38 | private PomPropertiesUtil util = new PomPropertiesUtil(); 39 | 40 | @TempDir 41 | Path tempDirectory; 42 | 43 | @Test 44 | void testCreatePomProperties() throws IOException { 45 | Path pomPropertiesFile = tempDirectory.resolve("bar.properties"); 46 | util.createPomProperties("org.foo", "bar", "2.1.5", new JarArchiver(), null, pomPropertiesFile); 47 | 48 | assertThat(pomPropertiesFile).exists(); 49 | Properties actual = new Properties(); 50 | actual.load(Files.newInputStream(pomPropertiesFile)); 51 | assertEquals("org.foo", actual.getProperty("groupId")); 52 | assertEquals("bar", actual.getProperty("artifactId")); 53 | assertEquals("2.1.5", actual.getProperty("version")); 54 | 55 | // Now read the file directly to check for alphabetical order 56 | List contents = Files.readAllLines(pomPropertiesFile, StandardCharsets.ISO_8859_1); 57 | assertEquals("artifactId=bar", contents.get(0)); 58 | assertEquals("groupId=org.foo", contents.get(1)); 59 | assertEquals("version=2.1.5", contents.get(2)); 60 | assertEquals(3, contents.size()); 61 | } 62 | 63 | @Test 64 | void testUnicodeEscape() throws IOException { 65 | Path pomPropertiesFile = tempDirectory.resolve("bar.properties"); 66 | util.createPomProperties("org.foo", "こんにちは", "2.1.5", new JarArchiver(), null, pomPropertiesFile); 67 | 68 | assertThat(pomPropertiesFile).exists(); 69 | Properties actual = new Properties(); 70 | actual.load(Files.newInputStream(pomPropertiesFile)); 71 | assertEquals("org.foo", actual.getProperty("groupId")); 72 | assertEquals("こんにちは", actual.getProperty("artifactId")); 73 | assertEquals("2.1.5", actual.getProperty("version")); 74 | 75 | // Now read the file directly to check for alphabetical order and encoding 76 | List contents = Files.readAllLines(pomPropertiesFile, StandardCharsets.ISO_8859_1); 77 | assertEquals("artifactId=\\u3053\\u3093\\u306B\\u3061\\u306F", contents.get(0)); 78 | assertEquals("groupId=org.foo", contents.get(1)); 79 | assertEquals("version=2.1.5", contents.get(2)); 80 | assertEquals(3, contents.size()); 81 | } 82 | 83 | @Test 84 | void testWhitespaceEscape() throws IOException { 85 | Path pomPropertiesFile = tempDirectory.resolve("bar.properties"); 86 | Path customPomPropertiesFile = tempDirectory.resolve("custom.properties"); 87 | try (Writer out = Files.newBufferedWriter(customPomPropertiesFile, StandardCharsets.ISO_8859_1)) { 88 | out.write("a\\u0020key\\u0020with\\u0009whitespace=value\\u0020with\\u0009whitespace\n"); 89 | out.write("zkey=value with \\\\ not at end of line\n"); 90 | out.write("ykey=\\tvalue with tab at beginning\n"); 91 | out.write("xkey=\\ value with whitespace at beginning\n"); 92 | out.write("wkey=\\u00E9\\u00FC\\u00E5\n"); 93 | } 94 | 95 | util.createPomProperties( 96 | "org.foo", "こんにちは", "2.1.5", new JarArchiver(), customPomPropertiesFile, pomPropertiesFile); 97 | assertThat(pomPropertiesFile).exists(); 98 | 99 | Properties actual = new Properties(); 100 | actual.load(Files.newInputStream(pomPropertiesFile)); 101 | assertEquals("value with\twhitespace", actual.getProperty("a key with\twhitespace")); 102 | assertEquals("value with \\ not at end of line", actual.getProperty("zkey")); 103 | assertEquals("\tvalue with tab at beginning", actual.getProperty("ykey")); 104 | assertEquals(" value with whitespace at beginning", actual.getProperty("xkey")); 105 | assertEquals("éüå", actual.getProperty("wkey")); 106 | 107 | // Now read the file directly to check for alphabetical order and encoding 108 | List contents = Files.readAllLines(pomPropertiesFile, StandardCharsets.ISO_8859_1); 109 | assertEquals(8, contents.size()); 110 | assertEquals("a\\ key\\ with\\twhitespace=value with\\twhitespace", contents.get(0)); 111 | assertEquals("artifactId=\\u3053\\u3093\\u306B\\u3061\\u306F", contents.get(1)); 112 | assertEquals("groupId=org.foo", contents.get(2)); 113 | assertEquals("version=2.1.5", contents.get(3)); 114 | assertEquals("wkey=\\u00E9\\u00FC\\u00E5", contents.get(4)); 115 | assertEquals("xkey=\\ value with whitespace at beginning", contents.get(5)); 116 | assertEquals("ykey=\\tvalue with tab at beginning", contents.get(6)); 117 | assertEquals("zkey=value with \\\\ not at end of line", contents.get(7)); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /src/test/resources/custom-pom.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | groupId = fake 19 | artifactId = bogus 20 | version = -1 21 | build.revision = 1337 22 | build.branch = tags/0.1.1 23 | -------------------------------------------------------------------------------- /src/test/resources/dummy.dot-1.5.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/maven-archiver/88b36991b2ff4b596a227a5ee8d256768c5372f6/src/test/resources/dummy.dot-1.5.jar -------------------------------------------------------------------------------- /src/test/resources/dummy1-1.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/maven-archiver/88b36991b2ff4b596a227a5ee8d256768c5372f6/src/test/resources/dummy1-1.0.jar -------------------------------------------------------------------------------- /src/test/resources/dummy1-1.1-20081022.112233-1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/maven-archiver/88b36991b2ff4b596a227a5ee8d256768c5372f6/src/test/resources/dummy1-1.1-20081022.112233-1.jar -------------------------------------------------------------------------------- /src/test/resources/dummy2-1.5.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/maven-archiver/88b36991b2ff4b596a227a5ee8d256768c5372f6/src/test/resources/dummy2-1.5.jar -------------------------------------------------------------------------------- /src/test/resources/dummy3-2.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/maven-archiver/88b36991b2ff4b596a227a5ee8d256768c5372f6/src/test/resources/dummy3-2.0.jar -------------------------------------------------------------------------------- /src/test/resources/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 4.0.0 22 | 23 | org.apache.maven.shared 24 | maven-shared-components 25 | 8 26 | 27 | org.apache.maven 28 | maven-archiver 29 | Maven Archiver 30 | 2.3-SNAPSHOT 31 | 32 | 33 | org.apache.maven 34 | maven-project 35 | 2.0 36 | 37 | 38 | org.codehaus.plexus 39 | plexus-archiver 40 | 4.8.0 41 | 42 | 43 | org.apache.maven 44 | maven-artifact 45 | 2.0 46 | 47 | 48 | 49 | scm:svn:http://svn.apache.org/repos/asf/maven/shared/trunk/maven-archiver 50 | scm:svn:https://svn.apache.org/repos/asf/maven/shared/trunk/maven-archiver 51 | http://svn.apache.org/viewvc/maven/shared/trunk/maven-archiver 52 | 53 | 54 | --------------------------------------------------------------------------------