| ------ |
| Supplementing Missing POM Information |
| ------ |
| John Casey |
| ------ |
| 2011-01-09 |
| ------ |
| |
| ~~ Licensed to the Apache Software Foundation (ASF) under one |
| ~~ or more contributor license agreements. See the NOTICE file |
| ~~ distributed with this work for additional information |
| ~~ regarding copyright ownership. The ASF licenses this file |
| ~~ to you under the Apache License, Version 2.0 (the |
| ~~ "License"); you may not use this file except in compliance |
| ~~ with the License. You may obtain a copy of the License at |
| ~~ |
| ~~ http://www.apache.org/licenses/LICENSE-2.0 |
| ~~ |
| ~~ Unless required by applicable law or agreed to in writing, |
| ~~ software distributed under the License is distributed on an |
| ~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| ~~ KIND, either express or implied. See the License for the |
| ~~ specific language governing permissions and limitations |
| ~~ under the License. |
| |
| Supplementing Missing POM Information |
| |
| <<Note:>> This feature was added in version 1.0-alpha-5. |
| |
| One of Maven's great strengths is that it allows you, the user, to build directly on the work of |
| others with minimal effort. For instance, by adding five lines (or less) to your POM, you can |
| declare a dependency on someone else's library, and instruct Maven to use that library during |
| the build for your own project. Since the library's JAR is usually accompanied by a POM of its |
| own, your project doesn't need to provide an exhaustive listing of all libraries used by all |
| of your direct dependencies. |
| |
| However, this approach of reusing POM metadata from your dependencies can be inhibited by a |
| dependency POM that provides less-than-complete information about its project. While most POMs |
| provide reasonably accurate information about their dependencies, they sometimes leave out some |
| information critical to assembling licensing and dependency notice files. |
| |
| For example, the templates used by many Apache distributions assemble a listing of project |
| dependencies according to their organization name (and URL), along with the URL each project's |
| website. When dependency POMs are missing this information, the dependency notice file |
| that the Remote Resources Plugin renders can be invalid. |
| |
| To compensate for incomplete dependency POMs, you can use the supplemental models support, introduced |
| to the Remote Resources Plugin in version 1.0-alpha-5, and improved in version 1.1. |
| |
| |
| * Fixing Incomplete POMs: Using Supplemental Models |
| |
| For those cases where your project's dependencies don't list organization name, organization URL, |
| project URL, or whatever other metadata you require for you legal notice files, the Remote Resources |
| Plugin allows you to configure a series of supplemental models. These models consist of one or more |
| model files, each of which contains one or more POM fragments that can be merged into existing |
| dependency POMs to supplement the metadata provided there. The plugin uses the key <<<groupId:artifactId>>> |
| to match each supplemental model with the dependency POM into which it should be merged. |
| |
| For example, imagine that your project's POM has declared the following two dependencies: |
| |
| +---+ |
| <dependency> |
| <groupId>org.foo</groupId> |
| <artifactId>missing-org-info</artifactId> |
| <version>1</version> |
| </dependency> |
| <dependency> |
| <groupId>org.foo</groupId> |
| <artifactId>missing-project-url</artifactId> |
| <version>1</version> |
| </dependency> |
| +---+ |
| |
| Now imagine that your project needs to include a file in its distribution that lists organization and |
| project URLs for each dependency, in a format like this: |
| |
| +---+ |
| From: Apache Software Foundation (http://www.apache.org/) |
| |
| - Commons FOO (http://commons.apache.org/foo/) org.apache.commons.foo:foo:1 |
| - Commons BAR (http://commons.apache.org/bar/) org.apache.commons.bar:bar:1 |
| +---+ |
| |
| However, as you try generating these licensing resources for your project, you quickly learn that your dependencies |
| provide POMs that don't always include all the information needed by this format. The first dependency is missing |
| all of the information provided by the <<<organization>>> element of the POM, and the second is missing a project- |
| specific URL (the <<<url>>> element of the POM). |
| |
| To fix these omissions for the purposes of resource generation, we can simply provide a supplemental-model file that |
| contains the missing information. The file, located at <<<src/main/appended-resources/supplemental-models.xml>>>, |
| would look something like this: |
| |
| +---+ |
| <?xml version="1.0" encoding="UTF-8"?> |
| <supplementalDataModels xmlns="http://maven.apache.org/supplemental-model/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| xsi:schemaLocation="http://maven.apache.org/supplemental-model/1.0.0 https://maven.apache.org/xsd/supplemental-model-1.0.0.xsd"> |
| <supplement> |
| <project> |
| <groupId>org.foo</groupId> |
| <artifactId>missing-org-info</artifactId> |
| |
| <organization> |
| <name>FOO, Inc.</name> |
| <url>http://www.foo.org/</url> |
| </organization> |
| </project> |
| </supplement> |
| <supplement> |
| <project> |
| <groupId>org.foo</groupId> |
| <artifactId>missing-project-url</artifactId> |
| |
| <url>http://www.foo.org/projects/missing-project-url/</url> |
| </project> |
| </supplement> |
| </supplementalDataModels> |
| +---+ |
| |
| Finally, we tell the Remote Resources Plugin to use the new supplemental-model file: |
| |
| +---+ |
| <plugin> |
| <artifactId>maven-remote-resources-plugin</artifactId> |
| <version>${project.version}</version> |
| <executions> |
| <execution> |
| <id>process-remote-resources</id> |
| <goals> |
| <goal>process</goal> |
| </goals> |
| <configuration> |
| <supplementalModels> |
| <supplementalModel>supplemental-models.xml</supplementalModel> |
| </supplementalModels> |
| [...] |
| </configuration> |
| </execution> |
| </executions> |
| </plugin> |
| +---+ |
| |
| After re-running the project build, the supplemental information we provided will be merged with the metadata |
| from the dependency POMs, providing enough information to complete the dependencies listing. |
| |
| |
| * Publishing and Reusing Supplemental Models |
| |
| <<Note:>> This feature was added in version 1.1. |
| |
| The configuration above is fine for single projects that need to address deficiencies in their dependencies' |
| metadata. But what happens when your organization wants to use these same deficient dependencies across multiple |
| projects? The configuration we just examined cannot handle reuse of supplemental-model files. |
| |
| To address this shortcoming, version 1.1 of the Remote Resources Plugin introduces a new parameter: |
| <<<supplementalModelArtifacts>>>. When combined with the <<<supplementalModels>>> parameter used above, this new |
| parameter allows the Remote Resources Plugin to resolve artifacts containing supplemental model information, then |
| search those artifacts for the paths given in the <<<supplementalModels>>> listing. |
| |
| To make the supplemental models above reusable using this mechanism, we first publish them in their own project: |
| |
| +---+ |
| <?xml version="1.0" encoding="UTF-8"?> |
| <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| <modelVersion>4.0.0</modelVersion> |
| |
| <groupId>org.myco</groupId> |
| <artifactId>dependency-resource-supplement</artifactId> |
| <version>1</version> |
| </project> |
| +---+ |
| |
| Note that this is just a simple, unadorned JAR artifact. We then move the above POM and <<<supplemental-models.xml>>> file |
| into a separate project directory structure: |
| |
| +---+ |
| |-- pom.xml |
| `-- src |
| `-- main |
| `-- resources |
| `-- supplemental-models.xml |
| +---+ |
| |
| Once we install this new project, we can reference it from the configuration for the Remote Resources Plugin, |
| like this: |
| |
| +---+ |
| <plugin> |
| <artifactId>maven-remote-resources-plugin</artifactId> |
| <version>${project.version}</version> |
| <executions> |
| <execution> |
| <id>process-remote-resources</id> |
| <goals> |
| <goal>process</goal> |
| </goals> |
| <configuration> |
| <!-- Reference the supplemental-model artifact from above --> |
| <supplementalModelArtifacts> |
| <supplementalModelArtifact>org.myco:dependency-resource-supplement:1</supplementalModelArtifact> |
| </supplementalModelArtifacts> |
| |
| <!-- Specify the path, relative to the JAR root, where the supplemental model file is located --> |
| <supplementalModels> |
| <supplementalModel>supplemental-models.xml</supplementalModel> |
| </supplementalModels> |
| [...] |
| </configuration> |
| </execution> |
| </executions> |
| </plugin> |
| +---+ |
| |
| Once the <<<supplemental-model>>> project is released and deployed, any number of projects can then make use of the |
| supplemental information it provides. |