问题
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
onshaker-multi-webapp
and obtain a deployable war; - run
Maven package
onshaker-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
onshaker-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>
回答1:
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 of0.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>
回答2:
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.
来源:https://stackoverflow.com/questions/25674839/maven-multi-module-error-assembling-war-webxml-attribute-is-required