Maven multi module: error assembling WAR: webxml attribute is required - java

I'm turning a single Eclipse Maven-managed webapp project in a multi-module Maven project (this is a test project to experiment with Maven, so feel free to provide any kind of suggestion).
The single project webapp doean't have any error, succesfully compiles and behaves correctly when deployed, so I'm starting with a working application.
The application has a web part and a console part, meaning that there are some classes with a main() method that when run from within Eclipse (with Run as -> Java Application) work as expected. Both parts show data from a database, queried either directly through JDBC or through jOOQ.
So, this is how I split the project:
core (holds everything common to the other two parts);
runnable (contains the classes that have a main() method);
webapp (the web application part).
Inside Eclipse, I have now 4 separate projects:
shaker-multi holds the aggregator (and parent) POM, plus each module in a subdirectory;
shaker-multi-core;
shaker-multi-runnable;
shaker-multi-webapp.
Inside Eclipse, core and webapp compile, and the latter can be deployed to a Tomcat instance and I can see it in the browser.
The problem arises with runnable. That project relies on jOOQ classes, so the relevant source code must be generated. The jOOQ dependencies and configuration are in core/pom.xml (since they may be used there too).
When I do Project -> Run As -> Maven build... -> clean generate-sources, on shaker-multi-core I get:
Non-resolvable parent POM: Failure to find sunshine.web:shaker-multi:pom:0.0.1
which sounds reasonable, since I didn't install any of those artifacts, even in my local repository.
But when I call Maven build... -> 'clean install' on shaker-multi, it breaks because it can't find the web.xml file for shaker-multi-webapp (although it correctly resides in shaker-multi-webapp/src/main/webapp/WEB-INF/web.xml).
What should I do?
Is my project configuration / splitting totally wrong?
Should I add another module with the parent POM? This sounds wrong, since the POM Reference states:
Inheritance and aggregation create a nice dynamic to control builds through a single, high-level POM. You will often see projects that are both parents and aggregators.
I'm totally lost here.
My expectations:
run Maven package on shaker-multi-webapp and obtain a deployable war;
run Maven package on shaker-multi-runnable and obtain a command line runnable jar (I still need to configure its POM to generate a jar-with-dependencies, though, I know);
run Maven package on shaker-multi and obtain some kind of bundle that I can move around and that will contain the war or the jar of each module.
EDIT
I added
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webXml>src/main/webapp/WEB-INF/web.xml</webXml>
</configuration>
</plugin>
to shaker-multi-webapp POM, as seen in this answer, but with no difference.
EDIT-2
I cleared my whole local repository (as suggested here), and when I reopened Eclipse, in the Maven console I saw
[...]
05/09/14 07:58:19 CEST: [INFO] Adding source folder /shaker-multi-webapp/src/main/java
05/09/14 07:58:19 CEST: [INFO] Adding source folder /shaker-multi-webapp/src/test/java
**05/09/14 07:58:19 CEST: [ERROR] Could not read web.xml**
[...]
Any hint? From where does it come from? I can't reproduce it though (without removing again my whole local repo).
This is shaker-multi POM:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>sunshine.web</groupId>
<artifactId>shaker-multi</artifactId>
<version>0.0.1</version>
<packaging>pom</packaging>
<modules>
<module>shaker-multi-core</module>
<module>shaker-multi-runnable</module>
<module>shaker-multi-webapp</module>
</modules>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
This is shaker-multi-core POM:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>sunshine.web</groupId>
<artifactId>shaker-multi</artifactId>
<version>0.0.1</version>
</parent>
<artifactId>shaker-multi-core</artifactId>
<packaging>jar</packaging>
<build>
<plugins>
<plugin><!-- jOOQ plugin--></plugin>
</plugins>
</build>
<dependencies>
<dependency><!-- jOOQ dependency --></dependency>
</dependencies>
</project>
This is shaker-multi-webapp POM:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>sunshine.web</groupId>
<artifactId>shaker-multi</artifactId>
<version>0.0.1</version>
</parent>
<artifactId>shaker-multi-webapp</artifactId>
<packaging>war</packaging>
<build>
<plugins>
<plugin><!-- Tomcat local -->
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>sunshine.web</groupId>
<artifactId>shaker-multi-core</artifactId>
<version>0.0.1</version>
</dependency>
<dependency>
<!-- JSP & Servlet dependencies -->
</dependency>
</dependencies>
</project>

I assume you folder structure is like this:
+-- shaker-multi
+--- pom.xml
+--- shaker-multi-core
+-- pom.xml
+--- shaker-multi-runnable
+-- pom.xml
+--- shaker-multi-webapp
+-- pom.xml
Furthermore you should check if your project works correctly on command and
NOT in Eclipse. So you should go to the root of your project
(shaker-multi folder) and
mvn clean package
This should produce no error etc.
One thing which comes into my mind is why do you use a release version instead of
a SNAPSHOT version for your project. So 0.0.1 instead of 0.0.1-SNAPSHOT?
A thing which you should improve is the definintion of maven-compiler plugin
in your parent:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
I would suggest to do it this way:
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
The encoding can be solved in a better way just define the following in your pom:
<project>
...
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
...
</project>
The above will define the default value for many plugin like maven-compiler-plugin,
maven-resources-plugin etc.
part from that your structure looks good ...one small improvement i would
suggest is if you define dependencies between your module:
<dependencies>
<dependency>
<groupId>sunshine.web</groupId>
<artifactId>shaker-multi-core</artifactId>
<version>0.0.1</version>
</dependency>
<dependency>
<!-- JSP & Servlet dependencies -->
</dependency>
</dependencies>
I would suggest to define inter module dependencies like this:
<dependencies>
<dependency>
<groupId>sunshine.web</groupId>
<artifactId>shaker-multi-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<!-- JSP & Servlet dependencies -->
</dependency>
</dependencies>

The whole problem here was really simple, and I feel a bit ashamed about it: but being the first time I did a multi–module project, I guess that could happen.
Of course, the details here hold when you work with all the project and modules sources by yourself: if you're in a team, working on only a part of the project and / or with a centralized private repository, then YMMV.
First of all, after I splitted the single–project into several modules, this was the situation in my Eclipse Project Explorer:
+-- shaker-multi
^--- pom.xml
^--- shaker-multi-core
^-- pom.xml
^-- (other content)
^--- shaker-multi-runnable
^-- pom.xml
^-- (other content)
^--- shaker-multi-webapp
^-- pom.xml
^-- (other content)
+-- shaker-multi-core
^-- pom.xml
+-- shaker-multi-runnable
^-- pom.xml
+-- shaker-multi-webapp
^-- pom.xml
Each +-- is a single, separated, Eclipse project. Each one of them has been singularly checked out from SVN (so they were, in fact, detached from one another).
I was, then, editing something in +-- shaker-multi-runnable and expecting that to work when I was running Maven on +-- shaker-multi, without svn–committing the former and svn–updating the latter.
That's why I kept getting the error in this question!
The proper way to handle such projects, if they come from an originally monolithic project is:
to split the code, resources, etc in subfolders;
to commit every change to the repository;
to erase every involved project in Eclipse.
Next, you go in the SVN Repositories tab of the IDE, expand the repository with the now splitted project and do Check out as Maven project of the parent–project (the one that has modules as subfolders).
If you, like me, are working with a recent version of Subclipse, you'll need the Maven Eclipse (m2e) SCM connector for subclipse 1.10 (svn 1.8) - update site (thanks go to buluschek development, see the last comments on that post), so that you can choose the repository path from the Check out as Maven Project dialog.
With it, you tell Eclipse to checkout the whole project from the parent folder, and the Eclipse automatically:
fetches all the Maven project modules;
creates a project corresponding to the parent–project, where modules are subfolders;
creates a separate project for every single module
links together each module project with the parent project, so that each edit in a module source code, resource, POM, etc is instantly reflected inside the folders of the parent-project.
That point (4) is the key here: although there are several projects, they have been linked together (I guess the same can be done when manually checking out each module folder, although I do not know how).
After having done this, all the Maven problems I had disappeared.

Related

maven war plugin does not forget about old files and dependencies and creates a war that contains removed files and dependencies

Hello I'm having a weird problem about war creation.
I use maven-war-plugin (tried with 3.1.0, 3.2.0, and 2.6). When I run war:war (or mvn clean package, or similars) the war is created but I noticed that it is like it always packages all the files and dependencies it encountered in the history of the project. I noticed this because the war file is always getting bigger and by opening it I see there are a lot of dependencies that I declared on the pom but now they are removed, and most importantly there are classes I deleted from the project! I even tried to start a new project and the result does not change.
I guess I'm using this badly... Is there something I should do to let him "forget" about the history and force it to consider the project "as it is" when creating a war?
Thanks for the help!
PS:
I always clean and compile before running war:war;
I work with IntelliJ IDEA Community 2017.3
using jdk 1.7 because of technical constraints.
Just for completeness, there is my pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>sduca-consumer-listener</groupId>
<artifactId>sduca-consumer-listener</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<sourceDirectory>src/main/java</sourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<webappDirectory>/sduca</webappDirectory>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<!-- Using Spring 4 because of jdk 1.7 -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
</dependencies>
</project>
EDIT1: I tried to change versions of maven-war-plugin, maven-compiler-plugin, and Maven itself, but nothing changes.
EDIT2: I tried changing the output directory, no changes. I tried to change version of the dependencies and as "expected" now the war includes both versions, becoming bigger and bigger...
EDIT3: I reinstalled IntelliJ IDEA, upgrading to the latest version. Nothing changes, it has only reset the content of the package, but it still "keep track" of the content and dependencies and still includes removed stuff on the package when creating a new one.
EDIT4: I've started using mvn clean compile war:war instead of mvn clean package and at first things started working, but then the problem of the existing old files returned. However, I find out that if I manually remove the exceding resources and *.class from the war it looks it works (at least it's deployed).
It's just a trick worked for me many times,
Backup your dependencies from pom.xml and delete it.
Do a clean build, it will show errors in all Java classes. Also delete the previous war.
Now, replace those backed up dependencies and clean build the webapp again. All errors will be disappeared and war file will be as expected.

Why is OSGI bundle module getting built twice

I am building this multi-module project with Maven. The folder structure of the project at root is as follows:
core (dir)
|--- pom.xml
|--- pom (dir)
|---com.loc.dist.core.msp.osgi.pom (dir)
|---pom.xml
|--- com.lgc.dist.core.msp.example.helloservice.client (dir)
|---pom.xml
Project com.lgc.dist.core.msp.example.helloservice.client is packaged as OSGI bundle and it is a child module of com.loc.dist.core.msp.osgi.pom
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.lgc.dist</groupId>
<artifactId>com.lgc.dist.core.msp.osgi.pom</artifactId>
<relativePath>../pom/com.lgc.dist.core.msp.osgi.pom</relativePath>
<version>0.1</version>
</parent>
<artifactId>com.lgc.dist.core.msp.example.helloservice.client</artifactId>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<groupId>com.lgc.dist</groupId>
<artifactId>com.lgc.dist.core.msp.service</artifactId>
<version>0.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<configuration>
<instructions>
<Export-Package>com.lgc.dist.core.msp.example.helloservice.client.*;version=${project.version}</Export-Package>
<Private-Package>com.lgc.dist.core.msp.example.helloservice.client.internal</Private-Package>
<Import-Package>*</Import-Package>
</instructions>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-scr-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
The pom.xml in top level shows pom folder and com.lgc.dist.core.msp.example.helloservice.client are in the reactor list.
<modules>
<module>pom</module>
<module>com.lgc.dist.core.msp.example.helloservice.client</module>
</modules>
When I ran mvn clean install from the root, it tends to build com.lgc.dist.core.msp.example.helloservice.client back to back twice. It is ok to install twice, but it will cause trouble when I run mvn deploy. All other submodules just built once. It is only the child modules of com.loc.dist.core.msp.osgi.pom are being built twice. I guess osgi builds all the bundle modules by default. But if I comment it out in pom.xml, the osgi bundle modules won't get built at all. What should I do to build these OSGI bundles just once?
EDIT It works fine if I change the packaging mode from bundle to jar, but that negates the purpose of having OSGI bundles.
Since the project "com.lgc.dist.core.msp.example.helloservice.client" is not a direct child of top level pom.xml, remove it from there.
So, in top level pom.xml, the entries should be :
<modules>
<module>pom/com.loc.dist.core.msp.osgi.pom</module>
</modules>
And pom.xml in pom/com.loc.dist.core.msp.osgi.pom should be having :
<modules>
<module>com.lgc.dist.core.msp.example.helloservice.client</module>
</modules>
After some research, it turns out maven-bundle-plugin 2.5.4 deploys the bundles by default. According to one of the answers of When using “bundle” packaging with maven-bundle-plugin goals are executed twice
(I'm surprised it did not get any up votes), you need to stop deploying by adding the execution block
<executions>
<execution>
<id>default-deploy</id>
<phase>no-execute</phase>
<goals>
<goal>deploy</goal>
</goals>
</execution>
</executions>
It is working now.
EDIT, based on the comment of this answer, it is resolved in 2.5.5. Haven't tried it though.

How to place folder/jar in Maven META-INF root

I am working on a implementation that requires UnlimitedJCEPolicyJDK8 for SAP hana cloud platform. The documentation tells me that i need to place it under the following structure:
WAR file:
META-inf
- ext_security
- jre8
The problem is when i include the jars it goes to WEB-INF/classes and thats not where the server is looking. As seen in the picture.
Technical details:
tomcat 8: v3.2 runtime
JRE 1.8
Maven build: using webapp archatype
With facades to support servlets.
IDE: eclipse
Tried the following:
add files using eclipse web deployment assembly (for what ever the reason it does not seems to work with maven and yes i use .m2 and WTP plugin)
Adding files trough maven dependency and tried copy to output folder.
i open WAR file moved files manually to correct folder and re-zipped and verified that if its in correct folder the update to server is working fine.
i really hope you can help me.
kind regards,
UPDATE: as requested by khmarbaise the pom file. And i created web-inf folder by myself in the hope it would be placed in root.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>hcp</groupId>
<artifactId>edi.web</artifactId>
<packaging>war</packaging>
<version>0.0.2-SNAPSHOT</version>
<name>edi.web Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- tried classpath but it did not seem to do annything
Below dependency is from local .m2 repository-->
<dependency>
<groupId>hcp</groupId>
<artifactId>jre8security</artifactId>
<version>1.0.0</version>
<optional>true</optional>
<!-- goes in manifest classpath, but not included in WEB-INF/lib -->
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
Solution provided by pace:
create a source folder under the following name: src/main/webapp/META-INF
The maven-war-plugin's war goal has a configuration option webappDirectory. It defaults to src/main/webapp. Anything in there will be placed in the root of the war. So you could create a directory:
src/main/webapp/META-INF
and drop in whatever files you want there. I don't much about the web tools plugin so not sure what approach would work there.

How to reference a non-maven project (in eclipse workspace) from a maven project?

I am working on a new project which is a plugin for a product.
I use maven to build my plugin (zip) but I need to reference the source code of the product which is defined in my Eclipse workspace. But this source code is not managed by Maven and I do not want to migrate it.
Is it possible to refers this workspace project by any way? (maven plugins, workaround welcome).
The dependency is just needed for the compilation inside Eclipse but will not be packaged in the plugin itself (provided scope).
I have also m2e in Eclipse and I want to keep this configuration when I make a "Maven Update".
UPDATE: I am looking for a solution which will work with a mvn clean install on a command line because I want to be able to execute the build from a CI platform (e.g. Jenkins)
Simply use Project -> Properties -> Java Build Path -> Projects -> Add
If you need to compile it outside Eclipse you can add a dependency to physical jar location:
<dependency>
<groupId>test</groupId>
<artifactId>test</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${basedir}/lib/test.jar</systemPath>
</dependency>
You might consider using the antrun plugin to trigger the compilation of your source code in the external project linked to your compile phase. You could even copy your .class files into your target folder so the runtime classpath finds them
Because I have already the compiled source and I do not need to recompile them (or to modify anything) I decided to package them using the pom assembly.
I made a separate project (under the same parent's than my plugins developement projects) called like openemm-src:
Parent project (openemm-plugin-dev)
|- plugin-1
|- plugin-2
|- openemm-src
|- pom.xml
The pom.xml for the openemm-src project looks like:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>openemm.plugin.dev</groupId>
<artifactId>plugin</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>openemm-src</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<name>OpenEMM Source Code Library</name>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptors>
<descriptor>src/assembly/src-plugin.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
<xecution>
</executions>
</plugin>
</plugins>
</build>
</project>
and the file src/assembly/src-plugin.xml:
<assembly>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>build/classes</directory>
<outputDirectory></outputDirectory>
</fileSet>
</fileSets>
</assembly>
After this, I refers the jar from the siblings projects like this:
<dependency>
<groupId>openemm.plugin.dev</groupId>
<artifactId>openemm-src</artifactId>
<version>1.0.0</version>
<scope>provided</scope>
</dependency>
This solution is looking more like a workaround, but this is because the OpenEMM project does not have any "Plugin Template Project" to be managed with Maven.
Note this is just a partial configuration and I had also to refers to the Agnitas libraries which did not contains all the source code (both were necessary to compile my code).

How to use Maven Checkstyle plugin in multi-module project?

This is my parent pom.xml (part of it) in a multi-module project:
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
…
This configuration instructs mvn to execute checkstyle plugin in the root project and every sub-module. I don't want it to work this way. Instead, I want this plugin to be executed only for the root project, and be skipped for every sub-module. At the same time, I have many sub-modules, and I don't like the idea of explicitly skipping the plugin execution in every one of them.
Documentation for Checkstyle says "..ensure that you do not include the Maven Checkstyle Plugin in your sub modules..". But how can I ensure that if my sub-modules inherit my root pom.xml? I'm lost, please help.
But how can I ensure that if my sub-modules inherit my root pom.xml?
To strictly answer this question, you can specify an <inherited> element inside a <plugin> definition. From the POM Reference:
inherited: true or false, whether or not this plugin configuration should apply to POMs which inherit from this one.
Something like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<!-- Lock down plugin version for build reproducibility -->
<version>2.5</version>
<inherited>true</inherited>
<configuration>
...
</configuration>
</plugin>
Some more advices/remarks (that may not apply):
You should always lock down plugin version for build reproducibility (you can enforce this rule with the Maven Enforcer Plugin).
People usually wants to use a a Custom Checkstyle Checker Configuration and/or a Suppressions Filter.
The Multimodule Configuration describes a typical setup allowing to share configuration files in large multimodules projects.
Perhaps you should separate your root pom into 2 separate entities: parent pom and aggregator pom. Your aggregator pom may even inherit from parent pom.
If you download latest project layout for hibernate, you will see this design pattern in action.
After this separation is done, you can define and execute checkstyle plugin just in aggregator/root pom. Because it is no longer a parent of your submodules it will not get inherited by them.
EDIT
Use <relativePath> when declaring <parent>
Just for demonstration, below is an example taken from the hibernate project structure.
The whole distribution can be found here-> http://sourceforge.net/projects/hibernate/files/hibernate3
Just so, that you have some context, here is a subset of their directory layout
project-root
|
+-pom.xml
|
+ parent
| |
| +-pom.xml
|
+ core
|
+-pom.xml
.. rest is scipped for brevity
project-root/pom.xml fragment
<parent>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-parent</artifactId>
<version>3.5.4-Final</version>
<relativePath>parent/pom.xml</relativePath>
</parent>
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
<packaging>pom</packaging>
<name>Hibernate Core Aggregator</name>
<description>Aggregator of the Hibernate Core modules.</description>
<modules>
<module>parent</module>
<module>core</module>
project-root/parent/pom.xml fragment
<groupId>org.hibernate</groupId>
<artifactId>hibernate-parent</artifactId>
<packaging>pom</packaging>
<version>3.5.4-Final</version>
project-root/core/pom.xml fragment
<parent>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-parent</artifactId>
<version>3.5.4-Final</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<packaging>jar</packaging>

Categories