1
\$\begingroup\$

I've been learning how to use Maven, and in order to understand it better, I want to try and write the smallest possible pom.xml file, while being as modern as possible, i.e. using java 1.8, utf-8, having the latest possible version of plugins and dependencies without breaking compatibility.

And so I came up with the following pom.xml and wanted to have other people's opinion on it.

<project>
  <modelVersion>4.0.0</modelVersion>

  <groupId>hello.maven</groupId>
  <artifactId>hello-maven</artifactId>
  <version>0.1.0</version>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.5.1</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>
    </plugins>
  </build>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>[4,5)</version>
    </dependency>
  </dependencies>
</project>

Edit: Is it possible to have a less redundant version number for maven-compiler-plugin in a way that maven picks the one appropriate to maven's own version?

\$\endgroup\$
1
\$\begingroup\$
<version>0.1.0</version>

In Maven, note that the concept of a version that is not released and is still in development is called a snapshot. This means that the version should not be a release version, like 0.1.0, but a snapshot version, like 0.1.0-SNAPSHOT. This is important because it distinguishes clearly what is a version in development and a released version.

As such, consider using a snapshot version here. It is when the Maven project is released, with the help of the maven-release-plugin, that the version will automatically be bumped to a release version (without SNAPSHOT) and tagged on version-control with it.

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-compiler-plugin</artifactId>
  <version>3.5.1</version>
  <configuration>
    <source>1.8</source>
    <target>1.8</target>
  </configuration>
</plugin>

That is a nice way to configure the Maven project to use Java 8. You can also do it in an alternate way. Both the source and target parameter of the maven-compiler-plugin have a corresponding user property, which are maven.compiler.source and maven.compiler.target, so you can set them in a <properties> section:

<properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
</properties>

This will have the same effect as the current <source> and <target> configuration.

Note that you could not specify a version for the Compiler Plugin in this case; it is the default version coming from the Maven installation that would be used (reference here for 3.3.9). In general, it is a good idea not to rely on this default version and specify explicitly the version to use: this helps in ensuring that the build does not depend on a given Maven version; also it documents clearly the version that is used.

<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>[4,5)</version>
</dependency>

Be careful when using version ranges. Ideally, you want to declare dependencies on a single fixed version of a dependency: using a version range is bad practice.

The big advantage of using a fixed version is that it makes it clear what is the expected version to use for your project. What specific version of JUnit do you want your project to depend on? Each version are very different, all of them with their respective features and bugs. With a range, you are basically saying "I don't really care, pick one in major version 4". You could even end up with a SNAPSHOT version (MNG-3092). It should be up to you to pick a version; you can upgrade it later if necessary.

Also, you should use the test scope for the JUnit dependency. It is only needed in the test classpath and is not a compile-time dependency of the main classes.

<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.12</version>
  <scope>test</scope>
</dependency>
| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.