Best practice for multiple project setup with m2eclipse
Example scenario: I have 2 projects, "common-project" and "application-project". The application-project depends on the API provided by common-project. There are also 3rd party jars (example guava) used by both projects.
I am trying convert to using maven and m2eclipse, but am unclear on the best approach. Currently, my maven-free setup has the 3rd party jars added as libraries on common-project, and marked as "exported". This way they are inherited by application-project, and I don't have to explicitly add them as libraries on application project. Both projects are under active development, so I would prefer not to have to build a jar of common-project first, then "install" that to my local repository before I can use the new features in application-project.
Wha开发者_StackOverflowt is the recommended approach for this type of project layout? I see the following thread touches roughly on the topic: Project in Eclipse that builds a jar used by another project in Eclipse
Thanks
Example scenario: I have 2 projects, "common-project" and "application-project". The application-project depends on the API provided by common-project. There are also 3rd party jars (example guava) used by both projects.
I would create 3 maven projects: a parent
aggregating module, a common-project
module and an application-project
module depending on common-project
and declare guava as dependency in the parent
module (so that child project will inherit it). Something like this:
$ tree Q3337426 Q3337426 ├── application-project │ ├── pom.xml │ └── src │ ├── main │ └── ... │ └── test │ └── ... ├── common-project │ ├── pom.xml │ └── src │ ├── main │ └── ... │ └── test │ └── ... └── pom.xml
Where the parent pom.xml looks like this:
<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>com.stackoverflow.Q3337426</groupId>
<artifactId>Q3337426</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<name>Q3337426 - Root</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>r05</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<modules>
<module>common-project</module>
<module>application-project</module>
</modules>
</project>
The pom.xml for the common-project:
<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>
<artifactId>Q3337426</artifactId>
<groupId>com.stackoverflow.Q3337426</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>common-project</artifactId>
<name>Q3337426 - Common Project</name>
<dependencies/>
</project>
The pom.xml for the application-project:
<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>
<artifactId>Q3337426</artifactId>
<groupId>com.stackoverflow.Q3337426</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>application-project</artifactId>
<name>Q3337426 - Application Project</name>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>common-project</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>
This is the Maven way to organize such a project and will allow to trigger a reactor build from the root project to build everything.
(...) Both projects are under active development, so I would prefer not to have to build a jar of common-project first, then "install" that to my local repository before I can use the new features in application-project.
The m2eclipse plugin can Resolve dependencies from Workspace projects (this is actually the default behavior). So if you import both application-project
and common-project
, the former would be configured to depend on the sources of common-project
(instead of depending on the jar). Changes made to common-project
will be immediately visible when using this setup.
This should solve your concern inside the IDE. Outside the IDE, run a reactor build on the top project.
Express the dependencies that each project has in the <dependencies>
element of the POM.
The m2eclipse plugin will then automatically pick these up, from the pom.xml, and add them as library references to the build path within Eclipse.
If application-project
depends on common-project
, then it will inherit it's dependencies as well - it will not be necessary to list the common dependencies between the two a second time in the pom.xml of application-project
.
Assuming you already have maven installed in your computer, then download the m2eclipse pluging install it and restart eclipse.
Remember the goal of a maven build is to produce and artifact that can be distributed and reused, it's OK if you don't want to make a mvn install
before having a somewhat stable version of you "common-project" API, although there is nothing wrong in doing it during development.
For your case you can do one of the following:
- If
common-project
API is absolutely necessary and will more often than not only be used in the confines of theapplication-project
then build your project as a multi-module project and declarecommon-project
to be a module of yourapplication project
. Here is an example of how to do this. - If otherwise
common-project
will be more often than not a shared artifact, then build each project independently having declared the dependencies of both in their pom.xml files eclipse should be able to figure out the dependency between the two. - You could develop a partial implementation of
common-project
first, package it, and then declaring as a dependency inapplication-project
with the<scope>system<scope>
specifying where in the file system it is located, this will tell maven that the dependency is always present and it would not look it up in any repository; although doing amvn install
will be more elegant than this you're trying to avoid that.
Regards.
精彩评论