Maven - Frequently Asked Questions

Development
Topics
Overview
Philosophy
Architecture
Source code
Project management
Coding style
Debugging
Tools
GitHub
Git
Maven
IDEs
Travis
AppVeyor
Dotfiles
Guides
Writing plugins
ImageJ Ops
Contributing to a plugin
Distributing your plugins
Development lifecycle
Building a POM
Developing with Eclipse
Hands-on debugging
Adding new ops
Adding new formats
Using native libraries
Tips for developers
Tips for C++ developers
ImageJ 1.x plugins
Versioning
Logging
Uber-JARs

What does the POM version mean?

The pom.xml of example-legacy-plugin inherits from a parent called pom-scijava. This parent POM defines and configures many things so that the POMs of individual plugin projects are shorter (i.e., so they don't have to repeat things) and more consistent (i.e., so they do not forget to define crucial metadata).

The version of pom-scijava (14.0.0 as of this writing) indicates the version of that parent POM. We occasionally improve the parent POM, adding and tweaking it. When we do so, its version increases. It is suggested to leave the version that same as what's in example-legacy-plugin, since that refers to the latest version. Future 1.x versions of ImageJ will be backwards compatible, so if you later notice that we have updated example-legacy-plugin to e.g. 15.0.0, you can (optionally) update your plugin to that version as well.

The version of example-legacy-plugin itself (0.1.0-SNAPSHOT as of this writing) is the version of your plugin. This string is appended to the JAR file name (e.g., example-legacy-plugin-0.1.0-SNAPSHOT.jar), so that you can differentiate between multiple versions of your plugin. Use whatever versioning scheme you want.

However, once you become more comfortable with Maven, we suggest using a SNAPSHOT version during development, and a release (i.e., non-SNAPSHOT) version when distributing your plugin. The reason is to avoid two different JAR files both called my-plugin-1.2.3 but with different contents. (This is part of what Maven calls reproducible builds.)

For example, while you develop your plugin, you might use the version 1.0.0-SNAPSHOT to indicate that this is not the final 1.0.0 version but leads up to it. Once you are happy with the plugin in its current form, switch to 1.0.0. Note, however, that you will cause problems if you later change the sources of the final 1.0.0 version (i.e., without first advancing the version in the pom.xml file).

How are dependency versions determined?

In many pom.xml files which extend pom-scijava, you can see that the dependency versions are omitted. The versions are defined (or "managed") by the pom-scijava parent configuration as part of its Bill of Materials—e.g., here is where the ImageJ 1.x version is defined.

  • Browse the latest pom-scijava here.
  • Browse the available versions of ImageJ 1.x here.

How do I determine which Maven projects (i.e., dependencies) I actually need?

One way to check is using the dependency plugin like so:

mvn dependency:analyze

This will tell you:

  1. Dependencies you declared but do not actually use; and
  2. Dependencies you did not declare directly, but actually need.

Note that this will only work if your project compiles successfully. In other words, it is easier to start with "too many" dependencies and pare down, rather than trying to "build up" from zero.

What's this: Property 'imagej.app.directory' unset; Skipping copy-jars

This is part of the imagej-maven-plugin (enabled for you by pom-scijava). As you suspected, it copies your plugin's .jar file to your ImageJ plugins folder. But you have to specify where:

mvn -Dimagej.app.directory=/Applications/ImageJ.app

You can cause this to happen automatically by creating a file $HOME/.m2/settings.xml where $HOME is your home directory, with the following contents:

<settings>
	<profiles>
		<profile>
			<id>imagej</id>
			<activation>
				<file>
					<exists>${env.HOME}/Desktop/Fiji.app</exists>
				</file>
			</activation>
			<properties>
				<imagej.app.directory>${env.HOME}/Desktop/Fiji.app</imagej.app.directory>
				<delete.other.versions>true</delete.other.versions>
			</properties>
		</profile>
	</profiles>
</settings>

With such user-wide settings in place, all your Maven builds will automatically copy the build artifacts into your ImageJ installation in $HOME/Desktop/Fiji.app. Of course, you can change this path to whatever you like.

How to use my own, custom ImageJ version?

The dependencies specified in pom.xml are only used to compile your .jar file. If you set the imagej.app.directory property properly, it will copy things into the jars/ subdirectory of the location you pointed the property to.

My software depends on a .jar file that is not available via Maven!

Write to the ImageJ Forum seeking assistance. The best solution is to get your dependency deployed to the ImageJ Maven repository.

See Playing Tradeoffs with Maven for an in-depth discussion of various solutions to this issue.

Can I call svnversion via Maven?

Typically you want to do that to put the current revision into an About box or something similar.

In general, you can call any needed Ant functionality using the maven-antrun-plugin. However, for the About box, there is a much better solution:

The pom-scijava parent uses the buildnumber-maven-plugin to embed the SCM revision and date in the JAR manifest.

Your About dialog box can access the information by adding a dependency on scijava-common like this:

<dependencies>
  <dependency>
    <groupId>org.scijava</groupId>
    <artifactId>scijava-common</artifactId>
  </dependency>
</dependencies>

and then using code like this:

import org.scijava.util.VersionUtils;

...
    String version = VersionUtils.getVersion(MyBeautifulPlugin.class);

How do I make my modified project available to a depending project using Maven?

See Using snapshot couplings during development.

How can I run individual tests with Maven?

As described here:

mvn -Dtest='TestCircle#mytest' test

Where can I find more information about Maven?

See the Maven page!