开发者

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:

  1. If common-project API is absolutely necessary and will more often than not only be used in the confines of the application-project then build your project as a multi-module project and declare common-project to be a module of your application project. Here is an example of how to do this.
  2. 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.
  3. You could develop a partial implementation of common-project first, package it, and then declaring as a dependency in application-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 a mvn install will be more elegant than this you're trying to avoid that.

Regards.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜