• Jan 15, 2019

I'm always on the lookout for ways to improve my projects' build process to get more-convenient results, cut down on IDE/compiler complaints, or to generally reduce the amount of manual work.

In the last couple weeks, I've figured out two changes to make that clean up my setup nicely: better source bundles and easier update sites.

Source Bundles

In OSGi parlance, a "source bundle" is a companion bundle/plugin for a normal bundle that contains the source code associated with it - for example, org.openntf.domino is paired with org.openntf.domino.source. With a bundle like this present, an IDE (Designer included) can pick up on the presence of the source code and use it for Javadoc and showing the original source of a class. It's extraordinarily convenient, rather than having to reference the source online or in another project (or not at all).

For a while, I've configured my Tycho projects to automatically generate these source bundles during build, and then I have ".source" features that reference them, which are then included in the final update site. This works very well, but it leaves the nagging problem that Eclipse complains about not being able to find the auto-vivified source bundles, and it also requires either putting the source bundles in the main features (which is a bit inefficient in e.g. a server deployment) or maintaining a separate ".source" feature.

It turns out that the answer has been in Tycho all along: instead of just generating source bundles, you can tell it to generate entire source features on the fly. You can do this by using the aptly-named tycho-source-feature-plugin:

<plugin>
	<groupId>org.eclipse.tycho.extras</groupId>
	<artifactId>tycho-source-feature-plugin</artifactId>
	<version>${tycho-version}</version>
	<executions>
		<execution>
			<id>source-feature</id>
			<phase>package</phase>
			<goals>
				<goal>source-feature</goal>
			</goals>
		</execution>
	</executions>
	<configuration>
		<includeBinaryFeature>false</includeBinaryFeature>
	</configuration>
</plugin>

With this, the build will auto-create the features as it goes, including pulling in the source of any referenced third-party bundles, and then you can include them in the final update site. For example, if the feature you're building is com.example.foo.feature, you can include com.example.foo.feature.source in your output.

Eclipse Repositories

Historically, the way Domino-targeted update sites are built is that they're referred to as the project type eclipse-update-site, which takes a site.xml and turns it into the final update site. This works well enough, but it has a couple problems. For one, it's deprecated and ostensibly slated for removal down the line, and it's best to not rely on anything like that. But otherwise, even when it works, it's fiddly: if you want to, for example, bring in a third-party feature, you have to explicitly specify the version of the feature you're bringing in, rather than letting the build environment pick up on what it is. This can turn into a drag over time, and it's always felt like unnecessary maintenance.

The immediate replacement for eclipse-update-site is eclipse-repository, which is very similar (you can "convert" by just changing the project type and renaming site.xml to category.xml) and solves the second problem. In a category.xml file, you can specify just the feature ID, leaving the version out or specified as 0.0.0, and it'll figure it out during the build.

However, this has a minor down side: though Designer can deal with these repositories without issue, the NSF Update Site template doesn't know about the generated artifacts.jar and content.jar files. You can use "Import Features", but that loses the feature categories, which are very useful when maintaining a large update site.

Fortunately, the site.xml format is extremely basic, so I created a Maven plugin a while ago to auto-generate one of these files. I improved it yesterday to pick up on the categories specified in the original category.xml file. This let me tweak the eclipse-repository project to shim in this generation before the final packaging:

<build>
	<plugins>
		<plugin>
			<groupId>org.darwino</groupId>
			<artifactId>p2sitexml-maven-plugin</artifactId>
			<version>1.1.0</version>
			<executions>
				<execution>
					<id>generate-sitexml</id>
					<goals>
						<goal>generate-site-xml</goal>
					</goals>
					<phase>package</phase>
				</execution>
			</executions>
		</plugin>
		<plugin>
			<groupId>org.eclipse.tycho</groupId>
			<artifactId>tycho-p2-repository-plugin</artifactId>
			<executions>
				<execution>
					<id>archive-repository</id>
					<goals>
						<goal>archive-repository</goal>
					</goals>
					<phase>package</phase>
				</execution>
			</executions>
		</plugin>
	</plugins>
</build>

Now it's sort of a "best of both worlds" deal: I can use the non-deprecated form of the repository and its improved features, while still using the stock NSF Update Site.

This Maven plugin is in OpenNTF's Maven repository, so you can add it in by adding the repo to your root project's pom:

<pluginRepositories>
	<pluginRepository>
		<id>artifactory.openntf.org</id>
		<name>artifactory.openntf.org</name>
		<url>https://artifactory.openntf.org/openntf</url>
	</pluginRepository>
</pluginRepositories>

 

Post New Comment