OSGi Report Maven Plugin
The goal of org.ops4j.tools.maven:osgi-report-maven-plugin Maven plugin is to generate a report containing formatted manifests of all OSGi bundles built, packaged and installed in OSGI Maven project.
The feature of org.apache.felix:maven-bundle-plugin (and underlying BND library) is automatic generation of META-INF/MANIFEST.MF and, what's most important here, Import-Package and Export-Package entries/headers.
When working on complex OSGi / Maven applications, it's sometimes hard to track why manifest contains given version range or version. Or why some packages are added in the first place. It's however easy sometimes to break something by upgrading Maven dependency and introducing new transitive Maven dependency and eventually getting incompatible OSGi manifest change when it's not desired.
Initial goal of osgi-report-maven-plugin is to provide set of goals related to meta information about OSGi manifests generated by maven-bundle-plugin and/or BND.
Goals
For now, there's only one Maven goal: manifest-summary.
manifest-summary
This goal generates text file (and automatically attaches it as installable/deployable Maven artifact) with a content like this (example for pax-web-api bundle):
At first glance it's long and not very helpful. But the intent was to allow comparing such reports before & after some dependency change.
Personally I ended up installing some bundles in Apache Karaf and checking output of bundle:headers command.
Configuration
There are several options when invoking this plugin.
Simplest way is to call:
mvn install org.ops4j.tools.maven:osgi-report-maven-plugin:0.1.1:manifest-summaryinside any project that produces an artifact which is proper OSGi bundle. This will generate a report inside target/ directory and attach it as deployable artifact. See:
[INFO]
[INFO] ---------------< org.ops4j.pax.logging:pax-logging-api >----------------
[INFO] Building OPS4J Pax Logging - API 1.11.0-SNAPSHOT
[INFO] -------------------------------[ bundle ]-------------------------------
...
[INFO] --- osgi-report-maven-plugin:0.1.0:manifest-summary (default-cli) @ pax-logging-api ---
[INFO] Processing org.ops4j.pax.logging:pax-logging-api:bundle:1.11.0-SNAPSHOT
[INFO] Attaching /data/sources/github.com/ops4j/org.ops4j.pax.logging/pax-logging-api/target/manifest-summary.txt
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5.903 s
[INFO] Finished at: 2019-01-29T13:07:57+01:00
[INFO] ------------------------------------------------------------------------We can configure the plugin inside any POM:
<build>
<plugins>
<plugin>
<groupId>org.ops4j.tools.maven</groupId>
<artifactId>osgi-report-maven-plugin</artifactId>
<version>0.1.0</version>
<executions>
<execution>
<id>default-manifest-summary</id>
<goals>
<goal>manifest-summary</goal>
</goals>
<!-- the below configuration is the default, so can be omitted -->
<configuration>
<report>${project.build.directory}/manifest-summary.txt</report>
<attach>true</attach>
<separateReports>${project.build.directory}/reports</separateReports>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>report and attach configuration parameters are optional and entire above <configuration> element can be skipped.
separateReports option is not enabled by default. If set to a directory, reports for individual bundles will be generated into corresponding files to make comparing the reports easier. For example, I used this option in pax-web 8.0.0-SNAPSHOT and got similar structure:
.
└── org
└── ops4j
└── pax
└── web
├── itest
│ ├── pax-web-itest-base
│ │ └── 8.0.0-SNAPSHOT
│ │ └── pax-web-itest-base-8.0.0-SNAPSHOT.bundle.txt
│ └── pax-web-itest-common
│ └── 8.0.0-SNAPSHOT
│ └── pax-web-itest-common-8.0.0-SNAPSHOT.jar.txt
├── pax-web-api
│ └── 8.0.0-SNAPSHOT
│ └── pax-web-api-8.0.0-SNAPSHOT.bundle.txt
├── pax-web-deployer
│ └── 8.0.0-SNAPSHOT
│ └── pax-web-deployer-8.0.0-SNAPSHOT.bundle.txt
...And finally there's the best way to add separate module to multi-project POM.
This plugin can collect all bundles packaged within multi-module Maven project and generate summary report for all the bundles. There are however few things to consider:
The report plugin has to be called last
The report plugin has to be called once
The report plugin has to be configured easily
Assuming project with a structure like:
project
+- module 1
+- module 2
+- module 2a
+- module 2b
+- module 3We have to add additional project with full POM like this:
<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 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<!-- optional, but recommended parent of current multi-module project -->
</parent>
<artifactId>osgi-report</artifactId>
<packaging>pom</packaging>
<build>
<plugins>
<plugin>
<groupId>org.ops4j.tools.maven</groupId>
<artifactId>osgi-report-maven-plugin</artifactId>
<version>0.1.0</version>
<extensions>true</extensions>
<executions>
<execution>
<id>default-manifest-summary</id>
<goals>
<goal>manifest-summary</goal>
</goals>
<!-- the below configuration is the default, so can be omitted -->
<configuration>
<report>${project.build.directory}/manifest-summary.txt</report>
<attach>true</attach>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>Remember to add osgi-report project as module to parent pom. The problem with ordering projects is resolved with this line:
<extensions>true</extensions>This instructs Maven to load Plexus component definitions from the plugin and use them. There's only one component that's provided by the plugin - a Plexus component with role = org.apache.maven.AbstractMavenLifecycleParticipant. Such component implements afterProjectsRead() method and ensures that the module with invocation of manifest-summary is built last (by adding dynamic dependencies on all (but itself and parents) remaining projects within reactor).
With such configuration, the invocation of this plugin is a matter of:
mvn clean validateThen, when running multi-module build (in debug mode - -X), we can see automatic dependency configuration to ensure that reporting module is run/built last:
...
[INFO] Adding dependencies to MavenProject: org.ops4j.tools.maven.it:osgi-report-multi-report:0.1.0 @ /data/sources/github.com/ops4j/org.ops4j.tools/maven/osgi-report-maven-plugin/src/it/osgi-report-multi-simple/report/pom.xml
[DEBUG] - Dependency {groupId=org.ops4j.tools.maven.it, artifactId=osgi-report-multi-p1, version=0.1.0, type=jar}
[DEBUG] - Dependency {groupId=org.ops4j.tools.maven.it, artifactId=osgi-report-multi-p4, version=0.1.0, type=jar}
[DEBUG] - Dependency {groupId=org.ops4j.tools.maven.it, artifactId=osgi-report-multi-pnested, version=0.1.0, type=pom}
[DEBUG] - Dependency {groupId=org.ops4j.tools.maven.it, artifactId=osgi-report-multi-pnested-p1, version=0.1.0, type=jar}
...