blob: 129fcb6d2eb0fcaf73ca27353961e82158058752 [file] [log] [blame]
------
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.
<The Maven developers highly recommend you use this as a last resort. There are good reasons why the defaults are
the way they are, and we strongly recommend you use them if you can. It encourages consistency and means one less
thing you ever need to worry about when starting a new project - there are more interesting things to do then
change your layout for the sake of it! Hopefully having used any of these techniques you find that Maven proves itself
capable, you will reconsider restructuring to address these issues.>
* 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: <<<core>>> and <<<module>>>.
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 <<<pom.xml>>> at the top level not to produce anything, but to include the other modules we plan to create:
+--------
<project>
<artifactId>my-parent</artifactId>
<packaging>pom</packaging>
...
<modules>
<module>core</module>
<module>module</module>
</modules>
</project>
+--------
Next, the modules themselves are created. Here is the <<<core/pom.xml>>> file you should create. The one in the
<<<module>>> subdirectory will be similar.
+--------
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>my-groupId</groupId>
<artifactId>my-parent</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>my-core</artifactId>
<build>
<sourceDirectory>../src/main/java</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<includes><include>**/core/**</include></includes>
</configuration>
</plugin>
</plugins>
</build>
</project>
+--------
In this example, the sources are found in the parent directory <<<../src/main/java>>>, and only Java files within a
<<<core>>> 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.