Maven Read properties plugin doesn't substitute values for dependencies - java

Following is my project structure.
test-proj
|_ src
|_main
| |_java
|_test
|_java
|_prop.properties
|_pom.xml
And my pom.xml
<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>com.sample</groupId>
<artifactId>test</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<!-- The resources tag will be used if prop file is under src location. -->
<!-- <resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources> -->
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.0.0</version>
<executions>
<execution>
<phase>initialize</phase>
<goals>
<goal>read-project-properties</goal>
</goals>
<configuration>
<files>
<file>${basedir}/prop.properties</file>
</files>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring-version}</version>
</dependency>
</dependencies>
</project>
Prop.properties file has
spring-version=3.1.0.RELEASE
I have tried to use maven-read properties plugin to read the properties and substitute the same in the place of spring version. But it throws up error saying 'dependencies.dependency.version' for org.springframework:spring-beans:jar must be a valid version but is '${spring-version}'.
I tried to use validate phase instead of initialize in the maven execution phase. But still the problem persists. Instead of context path, i tried replacing the property file location to be an absolute path D:\test-proj\prop.properties in configuration which didnt help me either. I am using maven compiler plugin version 2.3.2. Am I missing something? Please let me know if its feasible to substitute dependency versions by some other plugin as well.
Note: I will not be able to use parent-child pom relationship as all my projects are modular and they don't depend on the same parent

If you want multiple unrelated project share dependecies version you can use Bill of Material concept http://howtodoinjava.com/maven/maven-bom-bill-of-materials-dependency/
Create unrelated BOM project with packaging pom. Add shared dependencies to the project
Each your project must import the BOM project
Below is snippet from the example page
How to add BOM [Bill Of Materials] dependency
Maven provides a tag dependencyManagement for this purpose. You need to add the bom information in this tag as follows. I am taking the example of Spring bom file.
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>4.0.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
An added benefit of using the BOM is that you no longer need to specify the version attribute when depending on Spring Framework artifacts. So it will work perfectly fine.
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>

I cannot imagine that this is going to work. AFAIU Maven has to resolve dependencies prior to any build execution since how should it be able to create a proper classpath for executions otherwise?
Re:
I will not be able to use parent-child pom relationship as all my projects are modular and they don't depend on the same parent.
I think you are able. Establish a super-parent POM that contains appropriate setting(s) to be inherited by all and make all your projects' parents childs of this:
+- super-parent
+- pom.xml ... containing setting(s) for all
+- parent-project-1
+- ...
+- parent-project-2
+- ...
+- ...

Related

Maven uses old version of pom.xml

I've just started using Maven for one of my Java projects. It took me a few edits to get Maven to accept the pom.xml but I finally got it working. However, to my surprise it still uses an older version of the pom.xml!
The thing is that I can't even find it in the project's directory. I used Notepad++ for all my edits. When I open pom.xml it's the correct (latest) version. When I look into the JAR with jd-gui, it's the previous version that Maven was complaining about. This makes no sense. I tried deleting everything in the target directory and running 'maven clean' to no avail.
Here's the current 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>my.project</groupId>
<artifactId>solint</artifactId>
<version>1.0</version>
<name>SolInt</name>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<build>
<plugins>
<!-- Prepares Agent JAR before test execution -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<phase>process-classes</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<archive>
<manifestEntries>
<Can-Retransform-Classes>true</Can-Retransform-Classes>
<Premain-Class>my.project.Agent</Premain-Class>
</manifestEntries>
</archive>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.6</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.13</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.13</version>
</dependency>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.20.0-GA</version>
</dependency>
</dependencies>
</project>
The only way I've been able to force Maven to use the latest version of pom.xml is to copy the whole project to a different directory. I want to understand this mystery. Any ideas?
EDIT 1:
Here's how the JAR looks after mvn package. Note that this one has the correct pom.xml because I changed the root directory.
If you deleted everything, then the next copy of the jar file built should contain the at-that-time current pom.xml file.
However, if you are actually loading the JAR file out of the ~/.m2/repo cache, then you need to do a maven install to update the cache, and then the projects that use that JAR will get the last installed version.
I suggest you to take a look here to find out where your pom.xml should be located inside your folder structure.
Another important thing is to understand how your folders structure should be; for this, please take a look here.
Basically, you should have something like this:
+ Project Folder
|
+ src
|
+ main
|
+ java
|
+ {here goes your package, classes, etc.}
|
i.e.
|
+ com
|
+ sample
|
+ HelloWorld.java
|
+ pom.xml
Also it's important, that you can have poms inheriting from other Poms and you also could have aggregation to group several poms on a project, check this to get more info.
Also, I will suggest you to use a IDE instead just Notepad++, such IntelliJ or Eclipse; both have Maven Integration.

How to include all modules from pom project

I am looking for a way to include all the modules in a project from another pom.xml. So in my case I have a parent pom with packaging set to pom. It contains 3 child modules that implement my interfaces in another api module. I want to dynamically include all the child modules in my project in maven.
In this case I want to include the connector1, connector2, connector3 in another module without having to specifiy the connector1,2,3 implicitly.
connectors - packaging: pom
connector1 - packaging: jar
connector2 - packaging: jar
connector3 - packaging: jar
I tried including the connectors pom in my project but this did not work. I was hoping that specifying the parent package with pom would include the child modules but this did not work. Are there any workarounds for how to do this?
Update
This was more of peeve of mine because I wanted to simply add a single connector and have all the child module dependency jars for the project be included. This would make the pom a little simpler to read.
Instead of having to register all the child dependencies like so
<dependencies>
<dependency>
<groupId>com.foo</groupId>
<artifactId>connector1</artifactId>
<version>0.0.1</version>
</dependency>
<dependency>
<groupId>com.foo</groupId>
<artifactId>connector1-api</artifactId>
<version>0.0.1</version>
</dependency>
<dependency>
<groupId>com.foo</groupId>
<artifactId>connector1-etl</artifactId>
<version>0.0.1</version>
</dependency>
<dependency>
<groupId>com.foo</groupId>
<artifactId>connector1-persistence</artifactId>
<version>0.0.1</version>
</dependency>
<dependency>
<groupId>com.foo</groupId>
<artifactId>connector2</artifactId>
<version>0.0.1</version>
</dependency>
<dependency>
<groupId>com.foo</groupId>
<artifactId>connector2-api</artifactId>
<version>0.0.1</version>
</dependency>
<dependency>
<groupId>com.foo</groupId>
<artifactId>connector2-etl</artifactId>
<version>0.0.1</version>
</dependency>
<dependency>
<groupId>com.foo</groupId>
<artifactId>connector2-persistence</artifactId>
<version>0.0.1</version>
</dependency>
<dependency>
<groupId>com.foo</groupId>
<artifactId>connector2-other</artifactId>
<version>0.0.1</version>
</dependency>
...
</dependencies>
This is just an example to clarify the original question. It does not exist and would probably have reprocussions if it did work.
<dependencies>
<dependency>
<groupId>com.foo</groupId>
<artifactId>connector1</artifactId>
<version>0.0.1</version>
<type>pom</type>
<include>submodules</include>
</dependency>
<dependency>
<groupId>com.foo</groupId>
<artifactId>connector2</artifactId>
<version>0.0.1</version>
<type>pom</type>
<include>submodules</include>
</dependency>
</dependencies>
If I remember correctly I was creating a modular project for an ordering system where I had a common api that our internal system would use (REST). I was creating a routing system where I could route an order to a single fulfillment center based on a criteria of the order (country, priority taxes etc). Each of the fulfillment centers had their own api (connectors).
The example is greatly simplified in the original question to make it more the problem more concise. In the real project each connector (1,2,3) would have been a separate pom with multiple dependency jars. One for their client api, then some etl code to match with my original api.
I don't remember how I solved this. I think I just had to include the all the child dependencies.
One way is to create a fourth module which "wraps" the 3 modules as dependencies. This way you could depend on this wrapper module which would.
connectors - packaging: pom
connector1 - packaging: jar
connector2 - packaging: jar
connector3 - packaging: jar
connectorWrapper - packaging: pom (depends on the above three)
Although it would make more sense to explicitly declare a dependency for each connector especially that they are only three.
Alternative solution:
A more dynamic approach (although very much an overkill IMO) is to have this fourth module package the implementation modules in an assembly using a custom assembly descriptor. For example, inside connectorWrapper, you could write an assembly.xml:
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
<id>impl-modules</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>${project.basedir}</directory>
<includes>
<include>pom.xml</include>
</includes>
<useDefaultExcludes>true</useDefaultExcludes>
</fileSet>
</fileSets>
<moduleSets>
<moduleSet>
<useAllReactorProjects>true</useAllReactorProjects>
<includes>
<include>*:connector*</include>
</includes>
<binaries>
<includeDependencies>false</includeDependencies>
</binaries>
</moduleSet>
</moduleSets>
</assembly>
Note that the descriptor tells the assembly plugin to:
include all modules in the current project reactor, so when you run mvn clean package in the root project, it will include all modules
include only implementation modules (the connector modules), as specified in the include element having *:connector*.
Of course you'll need to configure the assembly plugin to use this descriptor in the connectorWrapper (or whatever other name you choose for this wrapper):
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptors>
<descriptor>assembly.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
Then you can run mvn install on the root project to install the assembly artifact, after which you can depend on it from the other project:
<dependencies>
<dependency>
<groupId>groupId</groupId>
<artifactId>connectorWrapper</artifactId>
<version>...</version>
<classifier>impl-modules</classifier> <!-- note the classifier -->
</dependency>
</dependencies>
Not entirely sure whether it exactly does what you need but within the latest maven releases you can use the scope import on your dependencies.
The first step would be to create a pom containing all the dependencies you would like to include in other projects:
<project>
<groupId>com.foo</groupId>
<artifactId>connectors</artifactId>
<version>0.0.1</version>
<packaging>pom</packaging>
<dependencies>
<dependency>
<groupId>com.foo</groupId>
<artifactId>connector1</artifactId>
<version>0.0.1</version>
</dependency>
<dependency>
<groupId>com.foo</groupId>
<artifactId>connector1-api</artifactId>
<version>0.0.1</version>
</dependency>
<dependency>
<groupId>com.foo</groupId>
<artifactId>connector1-etl</artifactId>
<version>0.0.1</version>
</dependency>
...
</dependencies>
</project>
In the projects you would like to include the connectors you have:
<dependency>
<groupId>com.foo</groupId>
<artifactId>connectors</artifactId>
<version>0.0.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
See Importing Dependencies for more information.
An alternative approach could be to use the maven assembly plugin and create a single (huge) jar containing all the classes you would like to include (single jar packaging); (for that you also need to create once a pom with all the dependencies and the assembly plugin).
I would write my own maven plugin for this. Judging from your reputation and the question, you could probably have something ready within the hour. Most probably sooner than researching and trying out solutions to do what you want.

Classloader with Maven built jar

I am working on a project which contains a number of subprojects. The structure is something like Project 1, Project 2 and ProjectClassLoader.
Using separate configuration files, I pass in the binary names of the classes from Projects 1 and 2 that need to be loaded each time as arguments to the ProjectClassLoader project.
The ProjectClassLoader gets a handle to the system classloader
ClassLoader loader = ClassLoader.getSystemClassLoader();
which in theory allows it to load any classes which are contained in the classpath.
I'm using Maven to build the projects and handle their associated dependences. Thus each project has it's own individual pom.xml file. The ProjectClassLoader defines a parent pom.xml over Projects 1 and 2 which inherit from this. The parent pom contains dependency entries for both Project 1 and 2.
My understanding was that any dependencies specified in the pom.xml files of these projects would get added to the classpath at runtime. However when trying to load classes using the system classloader, I'm getting class not found execptions.
I have tried using the mvn:exec plugin which I understand includes the dependencies in the classpath when executing jars on the command line but this has not worked.
I'd grately appreciate any help in furthering my understanding of why I can load the classes even though the dependencies are defined in the pom...Thanks in advance
Can you check if your pom matches this configuration a bit?
<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">
...
<properties>
...
<exec.maven.plugin.version>1.2.1</exec.maven.plugin.version>
...
</properties>
<build>
<plugins>
...
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
</plugin>
...
</plugins>
<pluginManagement>
<plugins>
...
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>${exec.maven.plugin.version}</version>
<configuration>
<executable>java</executable>
<arguments>
<argument>-classpath</argument>
<!-- automatically creates the classpath using all project dependencies, also adding the project build directory -->
<classpath />
<argument>com.example.Main</argument><!-- your mainClass -->
</arguments>
</configuration>
</plugin>
...
</plugins>
</pluginManagement>
</build>
<dependencies>
...
<dependency>
<groupId>groupId.for.project1</groupId>
<artifactId>project1</artifactId>
</dependency>
<dependency>
<groupId>groupId.for.project2</groupId>
<artifactId>project2</artifactId>
</dependency>
...
</dependencies>
<dependencyManagement>
<dependencies>
...
<dependency>
<groupId>groupId.for.project1</groupId>
<artifactId>project1</artifactId>
<version>${project1.version}</version>
</dependency>
<dependency>
<groupId>groupId.for.project2</groupId>
<artifactId>project2</artifactId>
<version>${project2.version}</version>
</dependency>
...
</dependencies>
</dependencyManagement>
...
</project>
Where you fill them with the correct artifacts.
You should then be able to start it with:
mvn exec:exec
Can you post your configuration for your pom plz if it doesn't match, that way it's easier to understand what exactly you currently have in your pom.

mvn generate-sources fails, why isn't xml beans on classpath?

I'm trying to generate java classes for OGC KML 2.2 as part of the maven generate-sources process using the org.codehaus.mojo xmlbeans-maven-plugin. The java code appears to be generated correctly, but I get tons of errors during compilation complaining that 'package org.apache.xmlbeans'. XMLBeans is clearly a dependency, it exists in my ~/.m2 repository, and I've been peek in the jar to make sure the classes are there. It looks like XMLBeans is successfully generating java files in target/generated-sources, but somehow its absent from the classpath during compilation.
I've tried changing the scope of the org.apache.xmlbeans dependency, but to no avail.
Here's the pom.xml
<modelVersion>4.0.0</modelVersion>
<groupId>net.opengis</groupId>
<artifactId>ogc-kml</artifactId>
<version>2.2.0</version>
<packaging>pom</packaging>
<name>ogc-kml</name>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>xmlbeans-maven-plugin</artifactId>
<version>2.3.3</version>
<executions>
<execution>
<goals>
<goal>xmlbeans</goal>
</goals>
</execution>
</executions>
<inherited>true</inherited>
<configuration>
<download>true</download>
<schemaDirectory>src/main/xsd</schemaDirectory>
</configuration>
</plugin>
</plugins>
</build>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.xmlbeans</groupId>
<artifactId>xmlbeans</artifactId>
<version>2.6.0</version>
</dependency>
</dependencies>
</dependencyManagement>
The project consists of a single src/main/xsd folder containing the two xsds from http://schemas.opengis.net/kml/2.2.0/. The entire folder structure is at https://github.com/iancw/maven-xmlbeans-question.
I can compile the classes by hand if I put the xmlbeans jar from my ~/.m2 repo on the classpath, e.g.
xmlbeans$ javac -classpath ~/.m2/repository/org/apache/xmlbeans/xmlbeans/2.4.0/xmlbeans-2.4.0.jar org/w3/x2005/atom/*.java org/w3/x2005/atom/impl/*.java net/opengis/kml/x22/*.java x0/oasisNamesTcCiqXsdschemaXAL2/*.java x0/oasisNamesTcCiqXsdschemaXAL2/impl/*.java net/opengis/kml/x22/*.java net/opengis/kml/x22/impl/*.java
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
xmlbeans$
I've looked through a number of examples and it seems like I'm doing this right. I haven't seen anyone else complain of this issue. Any maven mavens have suggestions?
(A curious side note is that although i've tried both 2.4.0 and 2.6.0 of the xmlbeans dependency, maven hasn't ever seemed to download the 2.6.0 version into my repository)
From the POM file that you've included in your question you have only defined the xmlbeans dependency in the dependencyManagement section. You also need to define it in your dependencies section of your POM before it will be included in the classpath at build time.
So for example your POM would be:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>xmlbeans-maven-plugin</artifactId>
...
</plugin>
</plugins>
</build>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.xmlbeans</groupId>
<artifactId>xmlbeans</artifactId>
<version>2.6.0</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<groupId>org.apache.xmlbeans</groupId>
<artifactId>xmlbeans</artifactId>
</dependencies>
One Additional issue that may look similar,
Check your java install jdk and ext folders for older beans jar.
The plugin puts the project dependencies at the end of the classpath.

Maven: javax.servlet specification deployed

I've a web application configured with Maven which uses a library, also configured with Maven and when I package geronimo-servlet_3.0_spec-1.0.jar is included in WEB-INF/lib and I don't understand why.
I check the library with mvn dependency:tree
$ mvn dependency:tree | grep geronimo
[INFO] +- org.apache.geronimo.specs:geronimo-servlet_3.0_spec:jar:1.0:provided
I check my web app:
$ mvn dependency:tree | grep geronimo
$
However when I run mvn:package the file gets included in WEB-INF/lib.
When I run mvn tomcat:run I can see:
INFO: validateJarFile(/home/stivlo/workspace/private/src/main/webapp/WEB-INF/lib/geronimo-servlet_3.0_spec-1.0.jar) - jar not loaded. See Servlet Spec 2.3, section 9.7.2. Offending class: javax/servlet/Servlet.class
Why and how to avoid? Thank you.
UPDATE 1: as requested I add the pom.xml
<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>org.obliquid</groupId>
<artifactId>test-webapp</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>private webapp</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<repositories>
<!-- For Jakarta ORO -->
<repository>
<id>mvnsearch</id>
<name>Maven Search</name>
<url>http://www.mvnsearch.org/maven2/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.obliquid.helpers</groupId>
<artifactId>obliquid-helpers</artifactId>
<version>0.9-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.4</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>private</finalName>
</build>
</project>
UPDATE 2: I followed the advice of Stephen C and modified the build section as follows:
<build>
<finalName>private</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war</artifactId>
<version>2.1</version>
<configuration>
<overlays>
<overlay>
<groupId>org.obliquid</groupId>
<artifactId>test-webapp</artifactId>
<excludes>
<exclude>WEB-INF/lib/geronimo-servlet_3.0_spec-1.0.jar</exclude>
</excludes>
</overlay>
</overlays>
</configuration>
</plugin>
</plugins>
</build>
However geronimo*.jar still gets included. I guess I've made a mistake in this configuration.
UPDATE 3: Stephen C. says that I should use
the groupId the artifactId of the WAR
file that contains the JAR file(s)
that you are trying to exclude.
I didn't know that WAR files could have a groupId and artifactId, in fact in my pom.xml I don't see any. My project builds a WAR file and has a groupId and an artifactId and those were the ones I tested above without success.
The dependency causing the problem is the following (is a JAR, not a WAR):
<dependency>
<groupId>org.obliquid.helpers</groupId>
<artifactId>obliquid-helpers</artifactId>
<version>0.9-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
If I try to use the groupId and artifactId listed in this dependency I've the following error:
[ERROR] Failed to execute goal
org.apache.maven.plugins:maven-war-plugin:2.1.1:war
(default-war) on project test-webapp:
overlay [ id
org.obliquid.helpers:obliquid-helpers]
is not a dependency of the project. ->
[Help 1]
If I try to use the groupId and artifactId of the JAR included by org.obliquid.helpers:
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-servlet_3.0_spec</artifactId>)
I have the same error.
[ERROR] Failed to execute goal
org.apache.maven.plugins:maven-war-plugin:2.1.1:war
(default-war) on project test-webapp:
overlay [ id
org.apache.geronimo.specs:geronimo-servlet_3.0_spec]
is not a dependency of the project. ->
[Help 1]
Reading the War plugin documentation, I found a section about creating skinny WARs. So I tried the following:
<build>
<finalName>private</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<packagingExcludes>WEB-INF/lib/geronimo-servlet_3.0_spec-1.0.jar</packagingExcludes>
</configuration>
</plugin>
</plugins>
</build>
Still without any success, geronimo-servlet_3.0_spec-1.0.jar is still there!
<groupId>org.obliquid.helpers</groupId>
<artifactId>obliquid-helpers</artifactId>
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-war-plugin:2.1.1:war (default-war) on project test-webapp: overlay [ id org.obliquid.helpers:obliquid-helpers] is not a dependency of the project. -> [Help 1]
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-servlet_3.0_spec</artifactId>
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-war-plugin:2.1.1:war (default-war) on project test-webapp: overlay [ id org.apache.geronimo.specs:geronimo-servlet_3.0_spec] is not a dependency of the project. -> [Help 1]
UPDATE 4: I discovered that the target/private.war file is not a zip of target/private/ directory, but the exclusions are done at packaging time and not by deleting files in target/private/ -- This means, I've to re-test all the things I did before.
Suggestion of gouki: doesn't work, the JAR is still there also in the WAR file.
Suggestion of Stephen C., maybe mis-understood: actually I just noticed that the pom.xml is always invalid whatever groupId/artifactId I put of the three possibilities explained above. So they didn't work for me.
What I found in the documentation (packagingExcludes), works.
Now, if I had to choose one of he answers I would choose Stephen C., because he helped me pointing at the documentation of the WAR plugin (I was reading in the wrong places). However I'd accept an answer that doesn't work, at least in the way I tried (probably wrong). So I'm not going to accept any answer, and add a new answer myself with the final working configuration.
UPDATE 5: I post the relevant part of the pom.xml of obliquid-helpers, that mentions geronimo-servlet_3.0_spec. I've marked it optional and with scope provided, still it gets included by a web-app, unless I mark it as "packagingExclude" in the maven-war-plugin configuration.
<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>org.obliquid.helpers</groupId>
<artifactId>obliquid-helpers</artifactId>
<version>0.9-SNAPSHOT</version>
<packaging>jar</packaging>
<name>obliquid-helpers</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<repositories>
[...]
</repositories>
<dependencies>
[...]
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-servlet_3.0_spec</artifactId>
<version>1.0</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
</dependencies>
</project>
Clearly, something has a dependency on that JAR file. If it is not showing up in the dependency tree, perhaps it is due to a dependency of your webapp WAR file on another WAR file that has this dependency.
If that is the case, then you could get add an <excludes> to the <overlay> element of the build descriptor for the WAR file plugin; e.g.
...
<build>
<finalName>webapp</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1</version>
<configuration>
<overlays>
<overlay>
<groupId>xxx</groupId>
<artifactId>yyy</artifactId>
<excludes>
<exclude>WEB-INF/lib/whatever.jar</exclude>
</excludes>
</overlay>
</overlays>
</configuration>
</plugin>
</plugins>
</build>
...
If you are using WAR file overlays, you should always include the clean target in the build. Otherwise you can get old dependencies hanging around in the WAR file. (IIRC, there is a Warning in the Maven output each time you build an overlaid WAR without cleaning!)
In fact, this could be the root cause of your problems. For instance, if previously you had the "geronimo" as an ordinary dependency and you haven't run mvn clean since then, the JAR file could still be hanging around.
Based from your pom.xml, the only dependency that might have dependency on geronimo servlet is
<dependency>
<groupId>org.obliquid.helpers</groupId>
<artifactId>obliquid-helpers</artifactId>
<version>0.9-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
Can you try excluding the geronimo in this dependency?
<dependency>
<groupId>org.obliquid.helpers</groupId>
<artifactId>obliquid-helpers</artifactId>
<version>0.9-SNAPSHOT</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-servlet_3.0_spec</artifactId>
</exclusion>
</exclusions>
</dependency>
First I want to thank gouki and Stephen C. for helping me. However their proposed solution didn't work for me. I'm grateful to them, but I can't accept their answer, because it would be misleading since it didn't work for this problem. I've upvoted Stephen C. answer, because he pointed me to the right documentation, which was essential to solve the problem.
Reading the WAR plugin documentation, especially the war:war mojo section, I've found an example on how to create Skinny WARs, which did the trick. So here is below the working configuration, to be added to the build section:
<build>
<finalName>private</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<packagingExcludes>WEB-INF/lib/geronimo-servlet_3.0_spec-1.0.jar</packagingExcludes>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
The archive part is probably not really needed, but I will find out when I deploy the WAR. The part that does the trick is the packagingExcludes tag, that can contain a comma separated list of tokens to exclude from the WAR before packaging.

Categories