Maven Guidelines

Use Maven POM only for simple configurations and avoid complex custom-builds in any single project. If complex custom-builds cannot be avoided, try splitting up the project in multiple simpler ones, so that each build step is more easily understandable. This can sometimes be done, by having simple base projects, which are than combined via projects, that are dedicated to only merging projects into one.

The reason for this is the fact, that in a Maven POM every component is dependent on every other component and that good logs or dependencies between components are hard to understand. This is caused by Maven's declarative design, which lacks double-entry bookkeeping regarding its inputs and outputs.

This problem is a none issue (most of the time), when one applies plugins like surefire for testing, sets the version of the Java compiler or uses the spotbugs plugin in order to find bugs. All of these none issues have in common, that they are either setting something general or writing something general to a folder. When one starts to transform and convert files via code (like ANT via the AntRun) in the POM, things start to get complicated and hard to understand. Therefore, avoid writing complex transformation rules in Maven POMs and instead prefer simple mapping rules when possible.

If complex file transformation rules are not avoidable, consider a dedicated plugin, that contains all possible transformation rules. Then one only needs to define the input paths and the outputs paths such a plugin. If the input and output paths are chosen smartly, one can also use the paths in order to understand the dependencies of POM components more easily. This is especially the case, when each input path has at most one corresponding output path.

This is mainly based on  Sonatype's release requirements  . The following elements are required, in order to be releasable:

  1. parent is required, in order to standardize POMs for non root POMs.
  2. name
  3. description
  4. url
  5. licenses/license
  6. scm/[url,connection,developerConnection]
  7. developers/developer, but only the main developers are required. It's best to list those people, who take responsibility for the project.

If there is any non-obvious problem with Maven or while using Maven, it is helpful to use the flags `--errors --debug` (which is equal to `-X and -e`), in order to get more details.

Never exit a state with the current thread marked as interrupted, as this will make the test failed. Also, note that the error message will not be very useful in this case, if `--errors --debug` is not used: `[ERROR] Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.1:java (default-cli) on project [...]: An exception occured while executing the Java class. java.lang.InterruptedException -> [Help 1]

When executing the unpack goal, one needs to consider, that by default, for every artifactItems any dependency is only unpacked once. If one creates multiple executions of maven-dependency-plugin, where each contains the same artifactItem, only the first execution will actually unpack the dependency and copy the unpacked files to the output folder. The following config, will only copy files of the jquery dependency to the folder ${basedir}/folder/a!

<build>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
        <version>3.7.1</version>
        <executions>
            <execution>
                <id>unpack-a</id>
                <phase>generate-resources</phase>
                <goals>
                    <goal>unpack</goal>
                </goals>
                <configuration>
                    <artifactItems>
                        <artifactItem>
                            <groupId>org.webjars</groupId>
                            <artifactId>jquery</artifactId>
                            <version>3.7.1</version>
                            <outputDirectory>${basedir}/folder/a</outputDirectory>
                            [...]
                        </artifactItem>
                    </artifactItems>
                </configuration>
            </execution>
            <execution>
                <id>unoack-b</id>
                <phase>generate-resources</phase>
                <goals>
                    <goal>unpack</goal>
                </goals>
                <configuration>
                    <artifactItems>
                        <artifactItem>
                            <groupId>org.webjars</groupId>
                            <artifactId>jquery</artifactId>
                            <version>3.7.1</version>
                            <outputDirectory>${basedir}/folder/b</outputDirectory>
                            [...]
                        </artifactItem>
                    </artifactItems>
                </configuration>
            </execution>
        </executions>
    </plugin>
</build>

Maven outputs a warning in this case, but this is documented here, because the warning skipping unpack can be quite irritating and unsuspicious. maven-dependency-plugin implements this skipping detection by putting an empty marker file for each unpacked dependency, at target/dependency-maven-plugin-markers/* (${project.build.directory}/dependency-maven-plugin-markers/*). Each such marker file contains the GAV coordinates of each unpacked dependency. In order to avoid this problem, one can place a dependency multiple times as an artifactItem inside a single artifactItems:

<build>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
        <version>3.7.1</version>
        <executions>
            <execution>
                <id>unpack-a</id>
                <phase>generate-resources</phase>
                <goals>
                    <goal>unpack</goal>
                </goals>
                <configuration>
                    <artifactItems>
                        <artifactItem>
                            <groupId>org.webjars</groupId>
                            <artifactId>jquery</artifactId>
                            <version>3.7.1</version>
                            <outputDirectory>${basedir}/folder/a</outputDirectory>
                            [...]
                        </artifactItem>
                        <artifactItem>
                            <groupId>org.webjars</groupId>
                            <artifactId>jquery</artifactId>
                            <version>3.7.1</version>
                            <outputDirectory>${basedir}/folder/b</outputDirectory>
                            [...]
                        </artifactItem>
                    </artifactItems>
                </configuration>
            </execution>
        </executions>
    </plugin>
</build>