简体   繁体   中英

How to set up maven for two separate projects that depend on the same jar

If this is answered somewhere else, kindly smack me and point me in the right direction.

I'm brand new to Maven and trying to wrap my head around how to use it with my projects. I've got two top level projects, one a Swing app, the other is a set of Web Services. They both depend on the same in-house jar. What are good ways to set up the poms for this?

If the jar was only used by one of the projects, then it looks like I'd move it down inside and make it a module. But I don't want two (and later more) copies of that jar's source code.

One way it looks like I could do this is to have a master pom for the Swing app that has the Swing app and the library jar as a modules. Then have another master pom for the Web app set up the same way. Would that make sense? Are there better ways?

The directory structure is currently very straightforward:

Development/  
----SwingApp/  
----WebServices/  
----CoreLibrary/  

Way too much info and side questions follow:

I've inherited a "build system" (using the term loosely) which is 100% Netbeans autogenerated ant scripts. I started trying to put it into Continuous Integration, TeamCity, which I really like. I've run into serious problems trying to build the WebServices project with it. There are things in the generated ant (build-impl.xml) that cannot be overridden in the CI environment as far as I can tell. Combine this with some serious classpath hell in day to day development and you're starting to see why I want to go to maven.

One of the issues wrapped up in this question is a habit developers on my team all seem to have. Right now the various projects in Netbeans have project references to the "CoreLibrary" project. What this means is that when source is changed in "CoreLibrary" and the developer does a build on a top level app, it will also build the CoreLibrary as necessary. Can that be simulated in Maven? It would go a ways to ease the transition. So far I'm seeing that Netbeans (6.7) doesn't do that with maven builds, and I don't think I can sell (yet) doing the day-to-day build work outside of Netbeans.

Within your Development directory you would have a pom which would look something like the following:

<project>
    <groupId>yourGroup</groupId>
    <artifactId>project</artifactId>
    <packaging>pom</packaging>
    <modules>
        <module>coreLibrary</module>
        <module>swingApp</module>
        <module>webServices</module>
    </modules>
</project>

yeah, I've left out some of the other elements, so fill in whatever else you need for a complete pom.

Then, your coreLibrary, swingApp, and webServices modules would each have a pom with a parent element, and any dependencies, as follows

<project>
    <parent>
        <groupId>yourGroup</groupId>
        <artifactId>project</artifactId>
        <version>yourVersion</version>
    </parent>
    <artifactId>webServices</artifactId>
    <packaging>war</packaging>
    <version>yourVersion</version>
    <dependencies>
        <dependency>
            <groupId>yourGroup</groupId>
            <artifactId>coreLibrary</artifactId>
            <version>yourVersion</version>
        </dependency>
    </dependencies>
</project>

If you build at the root level, then it will build all 3 modules, or, even better, you could use the --also-make option to build only webServices and its dependencies (in this case coreLibrary)

mvn -am --projects webServices clean install 

You shouldn't be adding the .jars into your projects. You should be adding JAR dependencies to your .pom files. Maven will download the .jars for you. You will have to create .pom files for each in-house .jar and add them to your maven repository (or proxy if you have one.)

Technically, there are several solutions to implement this build but, depending on the coupling between these project and their life cycles, you might end up choosing one option or the other. Some questions may help to decide:

  • Who is building all these projects? A unique team? Separated teams?
  • Is there any relations between the SwingApp and the WebServices? When you build the SwingApp, does it make sense to build the WebServices? When you release the SwingApp, do you release the WebServices too? Do the SwingApp and WebServices projects always use the same version of the CoreLibrary?
  • Does it make sense to build the 3 projects together?
  • Does it make sense to build the CoreLibrary separately and have both projects depend on the produced jar?

Based on the provided informations, my understanding (which may be wrong, it's just an interpretation) is that all 3 projects are actually tightly coupled and developed in the same time, by the same people. When the core library is modified, the dependent project are rebuilt. So, I'd suggest the following multi-modules project:

my-app/           // this is the parent module, it aggregates the child modules  
|-- pom.xml       
|-- core-library  
|   `-- pom.xml   
|-- swing-app     // this module has a dependency on core-library  
|   `-- pom.xml   
`-- web-services  // this module has a dependency on core-library  
    `-- pom.xml

The idea is to put all projects under a parent module and to use both project aggregation and project inheritance:

  • The parent project will be used to aggregate the child modules. It has a packaging of type pom and declare a <modules> element containing all 3 child modules. By doing so, the parent project now knows its modules, and if a Maven command is invoked against the parent project, that Maven command will then be executed to the parent's modules as well.
  • Each child module will declare the parent project as <parent> . This is useful to inherit common part from the parent pom
  • The swing-app and the web-services modules will have a <dependency> on core-library declared in their pom. During a multi-modules build, dependencies are use by maven to calculate the build order.

With this setup, the core-library will be build before swing-app and web-services when running Maven from the top project (this is called a multi modules build or reactor build) which seems to be the desired behavior. This seems thus equivalent to the actual situation without the messy local JARs management (with maven, dependencies are managed through a "local repository" and this is a built-in feature).

Note: If NetBeans doesn't like nested modules, it's possible to use a flat layout like this (but this is more a detail for now):

my-app/           
|-- parent
|   `-- pom.xml       
|-- core-library  
|   `-- pom.xml   
|-- swing-app     
|   `-- pom.xml   
`-- web-services  
    `-- pom.xml

For implementation details, the Multi Module Project with Eclipse might help you to get started very fast, just skip the Eclipse specific steps. Or check out the Chapter 6. A Multi-module Project of Sonatype's Maven book for a "real" reference.

Let each of the application and the jar library be a module inside a trivial parent. Let both applications depend on the core, and maven will figure out the order in which to build things.

I've got two top level projects, one a Swing app, the other is a set of Web Services. They both depend on the same in-house jar.

Are you using your own Maven repository? If so, the simplest option is to simply deploy the common in-house JAR and have both projects depend on the JAR, using the <dependency> element in the POM.

Nexus is a really great and easy to use repository, if you are going to use Maven in-house then you will no doubt want to run your own repository so you can actually "release" versions of each project, library JARs, etc. Repository Management with Nexus is a free book from Sonatype that details how to use it, best practices, etc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM