Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I make one Maven module depend on another?

OK, I thought I understood how to use Maven...

I have a master project M which has sub-projects A, B, and C. C contains some common functionality (interfaces mainly) which is needed by A and B. I can run mvn compile jar:jar from the project root directory (the M directory) and get JAR files A.jar, B.jar, and C.jar. (The versions for all these artifacts are currently 2.0-SNAPSHOT.)

The master pom.xml file in the M directory lists C under its <dependencyManagement> tag, so that A and B can reference C by just including a reference, like so:

<dependency>
    <groupId>my.project</groupId>
    <artifactId>C</artifactId>
</dependency>

So far, so good. I can run mvn compile from the command line and everything works fine. But when I open the project in NetBeans, it complains with the problem: "Some dependency artifacts are not in the local repository", and it says the missing artifact is C. Likewise from the command line, if I change into the A or B directories and try to run mvn compile I get "Build Error: Failed to resolve artifact."

I expect I could manually go to where my C.jar was built and run mvn install:install-file, but I'd rather find a solution that enables me to just work directly in NetBeans (and/or in Eclipse using m2eclipse).

What am I doing wrong?

like image 755
Daniel Pryden Avatar asked Mar 24 '10 22:03

Daniel Pryden


People also ask

Can two Maven modules depend on each other?

Because modules within a multi-module build can depend on each other, it is important that the reactor sorts all the projects in a way that guarantees any project is built before it is required. The following relationships are honoured when sorting projects: a project dependency on another module in the build.

How do I add one project as dependency in Maven?

Right-click the utility project, and select Maven>Add Dependency. Type a dependency name in the Enter groupID… field (e.g., commons-logging) to search for a dependency. Select the dependency, and click OK.


3 Answers

Maven relies on the concept of binary dependencies and resolves them through the local repository. In other words, you need to "install" packages in your local repository if you have dependencies between them, compiling and packaging code is not enough. And to do so, you need to run install (that will install the package into the local repository, for use as a dependency in other projects locally).

Side note: you shouldn't invoke mvn compile jar:jar but prefer mvn package. First, running the package phase will trigger all the phases before package (including compile) and package itself. Second, running package will invoke jar:jar, or war:war, etc depending on the <packaging> value of the project (check the introduction to the lifecycle for more details on this). That's one of the big strength of Maven: you don't need to know if the project is a JAR, a WAR, an EJB, etc and to run the appropriate goal to package it. Just run the standardized package phase and Maven will do the job (using the default goals bindings).

That was for the Maven theoretical part. Inside IDEs, things might be slightly different to make working with Maven more convenient. IDEs may use project dependencies (i.e. dependencies on code inside the IDE) instead of binary dependencies so that changes made in one project are made visible in other modules without having to run mvn install. This is the case of Eclipse + M2Eclipse. And this applies also to NetBeans under the following condition (see Dependency Management):

Hint: If you open a project that other projects depend on, the icon in other projects changes to a "maven project" icon to denote that the IDE knows about link between the projects. However such a link is only established when the groupId, artifactId and version all match in the dependency and project declaration. Frequently occurring problem is that you change an API signature in your library project, but the application is not picking up. Often it's caused by the fact that the application is using an older version of the library artifact. The artifact icon can help you track down these problems.

like image 83
Pascal Thivent Avatar answered Oct 18 '22 06:10

Pascal Thivent


You need to run mvn install instead of mvn compile. The install goal will copy the built jar into the local repository after compiling and packaging it. If you only run compile, it will only compile the class files into the target directory and not make them available to other projects.

In Eclipse, if you import a pom from the top level, it will import the subprojects into separate Eclipse projects and set up the dependencies of related projects then set up each project's classpath to depend on others. I'm not familiar with Netbeans but I am pretty sure there is some way to do the same thing.

like image 35
Ken Liu Avatar answered Oct 18 '22 04:10

Ken Liu


netbeans links projects together by the local repository content, so mvn install is necessary in most scenarios.

like image 31
mkleint Avatar answered Oct 18 '22 05:10

mkleint