Web-hosted CSS and the Maven Javadoc plugin

The Maven Javadoc plug-in allows to generate JAR files that contain the Javadoc of a given project/module. This is necessary, as an example, when you want to publish your artifacts to Maven Central or Sonatype OSS repositories.

If you look at the options of this plug-in, you can see there are only two solutions to use a custom CSS stylesheet. Either this CSS file is located on your file disk, or it is located in a Maven dependency. For a project I am working on, we had this stylesheet located on a web server. We wanted Maven to download this file during the build process and add it to the generated JAR. I thus submitted a PR to upgrade the CSS pick action to an URL.

After some discussions, we finally agreed with Michael Osipov that there were alternative solutions to changing the code. So, here is the option I kept. During the generate-sources phase, we download the remote CSS stylesheet somewhere over the disk. And we then pass the file’s location to the Javadoc plug-in.

<build>
	<plugins>
		<!-- Download the stylesheet for the javadoc -->
		<plugin>
			<groupId>org.apache.maven.plugins</groupId>
			<artifactId>maven-antrun-plugin</artifactId>
			<version>1.8</version>
			<executions>
				<execution>
					<phase>generate-sources</phase>
					<configuration>
						<exportAntProperties>true</exportAntProperties>
						<target>
							<tempfile property="dir" destdir="${java.io.tmpdir}" />
							<mkdir dir="${dir}" />
							<property name="javadoc.stylesheet" value="${dir}/roboconf-javadoc.css" />
							<get src="${build.resources.url}/javadoc/stylesheet.css" dest="${javadoc.stylesheet}" />
						</target>	
					</configuration>
					<goals>
						<goal>run</goal>
					</goals>
				</execution>
			</executions>
		</plugin>

		<plugin>
			<groupId>org.apache.maven.plugins</groupId>
			<artifactId>maven-javadoc-plugin</artifactId>
			<version>${javadoc.plugin.version}</version>
			<executions>
				<execution>
					<id>attach-javadoc</id>
					<goals>
						<goal>jar</goal>
					</goals>
					<configuration>
						<stylesheetfile>${javadoc.stylesheet}</stylesheetfile>
					</configuration>
				</execution>
			</executions>
		</plugin>
	</plugins>
</build>

Notice that I use the Maven ANT plug-in to create a directory in the OS’ temporary directory. The ANT plug-in must at least be in version 1.7, as we export ANT properties as Maven properties. Notice also that I download the file only once and cache it in a same location, for all the modules. It avoids downloading N times when we have a multi-module project.

You might also use download single mojo instead of ANT. Eventually, Michael also suggested a pure HTML solution, using…

@import url("http://example.com/my-stylesheet.css")

But this is not exactly what we wanted to do.
With this last option, Maven artifacts assume the web server will ALWAYS be available, while the initial approach requires the server to be online at build time only.

The PR could have been useful, but I was not going to fight about it. This use case is somehow very limited, and the alternatives listed here are not that hard to setup.


About this entry