------ Guide to Using Maven when You Can't Use the Conventions ------ Brett Porter ------ 2005-12-05 ------ ~~ Licensed to the Apache Software Foundation (ASF) under one ~~ or more contributor license agreements. See the NOTICE file ~~ distributed with this work for additional information ~~ regarding copyright ownership. The ASF licenses this file ~~ to you under the Apache License, Version 2.0 (the ~~ "License"); you may not use this file except in compliance ~~ with the License. You may obtain a copy of the License at ~~ ~~ http://www.apache.org/licenses/LICENSE-2.0 ~~ ~~ Unless required by applicable law or agreed to in writing, ~~ software distributed under the License is distributed on an ~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ~~ KIND, either express or implied. See the License for the ~~ specific language governing permissions and limitations ~~ under the License. ~~ NOTE: For help with the syntax of this file, see: ~~ http://maven.apache.org/doxia/references/apt-format.html Using Maven When You Can't Use the Conventions There is a common misconception that Maven can't build a project that doesn't conform to certain directory structures or build practices. This often isn't the case - however it is true that some Maven features or plugins (especially by third parties) may not work or work completely. This guide will help you set up Maven on your project when the directive from on high is to not change the existing layout, and detail some of the feature that you might miss when doing so. * Using Multiple Source Directories This occurs when you are producing a single JAR (or other artifact), and have several source directories with classes you want to include. ** Why isn't this recommended? ... ~~TODO ** How do I do this? ... ~~TODO ** What are the limitations? There should be no limitations in this approach. Maven natively supports multiple source directories for the purposes of generated sources. * Producing Multiple Unique JARs from a Single Source Directory As many people that complain about not being able to spread out their sources into multiple source directories seem to complain about not wanting to spread anything out, producing several unique artifacts from a single directory using includes and excludes. ** Why isn't this recommended? This practice can be confusing and risky. * You may end up building two JARs that include the same classes - this indicates that the common functionality should have been abstracted into a separate dependency. * You may end up introducing a dependency between the two JARs that you didn't realise, and often a circular dependency. This indicates that the classes are in the wrong JAR, or perhaps that everything should just be a single JAR. ** How do I do this? You still should adhere to producing one artifact per POM, but this requires having multiple POMs, and hence multiple subdirectories. The positive to this is that these introduced directories won't change the layout of existing code, and will establish a future layout should you decide to separate. Here is an example of setting it up when there is a project with two JARs produced: <<>> and <<>>. You might like to review the {{{../getting-started/} Getting Started Guide}} ~~ or {{{guide-multi-module.html} Guide to Using Multiple Modules}} that demonstrates how this is normally done in Maven, as it is quite similar. Your directory will look something like this: -------- / +- pom.xml +- src/ +- main/ +- java/ +- core/ +- Core.java +- module/ +- Module.java -------- First, you set up your <<>> at the top level not to produce anything, but to include the other modules we plan to create: -------- my-parent pom ... core module -------- Next, the modules themselves are created. Here is the <<>> file you should create. The one in the <<>> subdirectory will be similar. -------- 4.0.0 my-groupId my-parent 1.0-SNAPSHOT my-core ../src/main/java maven-compiler-plugin 2.0.2 **/core/** -------- In this example, the sources are found in the parent directory <<<../src/main/java>>>, and only Java files within a <<>> package are included. The final result when building will look like this: -------- / +- pom.xml +- src/ +- main/ +- java/ +- core/ +- Core.java +- module/ +- Module.java +- core/ +- pom.xml +- target/ +- my-core-1.0-SNAPSHOT.jar +- module/ +- pom.xml +- target/ +- my-module-1.0-SNAPSHOT.jar -------- ** What are the limitations? There is no universal inclusion/exclusion specification, so each plugin needs to be configured individually, and some might not have that capability. In particular, expect that site reports may include all sources, for example. * Producing Multiple JARs from a single POM Source directories aside, sometimes people desire to produce multiple JARs from a single POM. Depending on your use case, Maven can support this. * If you are looking to produce JARs that are different (ie, they have their own dependencies and metadata), Maven doesn't support this. This usually is only needed when sharing a source directory for intrinsically different things, so the use case above applies instead. * If you are producing a JAR that is a derivative of the original (eg, just a subset of classes, or the same JAR with debugging enabled), the Maven supports this completely using profiles. See {{{../introduction/introduction-to-profiles.html} Introduction to Profiles}} for more information.