Satisfying Designer's Peculiar OSGi Constraints in Tycho
Mon Oct 12 17:33:14 EDT 2015
Before anything else, I should mention that this post is entirely on the topic of building OSGi plugins with Maven. If you're not doing that yet, this probably won't be particularly useful.
For the most part, when building OSGi plugins for XPages, you can be fairly confident that the available plugins will be fairly similar between Notes and Domino. That's not quite always the case, though - there are a set of plugins that are available in Domino that aren't present in Designer's runtime. They're generally physically there in the Notes install, in the osgi
folder, but are presumably only loaded when you (inadvisably) fire up the local web preview.
In this situation, you may want to make your XPages library depend on a server plugin, but doing a normal OSGi dependency will cause it to fail to load in Designer. OSGi provides a clean mechanism for this: optional dependencies. If you mark a dependency (on a plugin or on a Java package) as optional, its absence will not prevent the plugin from loading. As long as the code that requires those classes is never run (as would be the case for server code loaded in Designer), you're in the clear.
However, when working on plugins with Maven, I've found it useful in a couple cases to tell Tycho to ignore optional dependencies to prevent it from choking on unimportant cascading dependencies or other issues. The trouble is when you combine these two techniques: now Tycho won't bother loading your optionally-required plugin, and so it won't have the classes available when it goes to compile your code.
A solution to this is to force Tycho to include the plugin in its view of the world regardless of what the MANIFEST.MF files say. This is accomplished in the target-platform-configuration
plugin entry that shows up in your average Tycho pom.xml file. If you've started from the same starting point as most, the required section will already be in there: in the configuration
, there should be a node named dependency-resolution
and then one within that named extraRequirements
. This allows you to shoehorn in these types of extra plugins - it's used in the normal case here for the "shim" Notes API plugin to avoid a dependency on Notes.jar. The same can be done for these non-Designer plugins:
<plugin> <groupId>org.eclipse.tycho</groupId> <artifactId>target-platform-configuration</artifactId> <version>${tycho-version}</version> <configuration> <!-- snip --> <dependency-resolution> <optionalDependencies>ignore</optionalDependencies> <extraRequirements> <requirement> <type>eclipse-plugin</type> <id>com.ibm.notes.java.api.win32.linux</id> <versionRange>9.0.1</versionRange> </requirement> <requirement> <type>eclipse-plugin</type> <id>com.ibm.domino.xsp.bridge.http</id> <versionRange>9.0.1</versionRange> </requirement> </extraRequirements> </dependency-resolution> </configuration> </plugin>
Once that's in place, Tycho will include the plugin in its build and will be able to compile properly.
Incidentally, this technique has also proven useful in executing test cases in a setup that makes heavy use of fragments. Tycho won't automatically pick up all fragments when constructing a test environment, but you can force it to include them by adding an extra requirement on a feature that references them. For example:
<!-- snip --> <extraRequirements> <requirement> <type>eclipse-feature</type> <id>some.parent.feature</id> <versionRange>0.0.0</versionRange> </requirement> </extraRequirements>
This is the sort of Maven/OSGi interaction that brings joy to my heart and grey to my hair.