Maven 2 - 'mvn test' does not find internal project plugin dependency - maven-2

I have a multi-module maven project (maven 2.2.1).
One of the module is a maven plugin.
This plugin is bound to the compile phase of another module, and added as a direct dependency to trigger correct reactor ordering of module's building.
If I run 'mvn clean install' on the root module, with a fresh local repository, everything goes fine (build, test, install). (I precise that my project's artifacts are not deployed anywhere, only installed locally in my machine's local repo).
BUT if I delete my local repository, and perform 'mvn test', the plugin module is reported as missing ? Whereas, the build order is correct, the plugin module is built succesfully before the module using it ???
Is there any special treatment of maven module with 'maven-plugin' packaging ?
I don't understand why other project inter modules dependencies are resolved correctly and not this specific one !

The problem is that a Maven Plugin must be installed into the local repository first before you can use a plugin as a dependency (or better be part of the life-cycle).

Related

Does mvn clean install runs the surefire test before updating .m2 repository

How does mvn clean install works
mvn install should execute all the phases before install phase, that means it will first run the surefire test and then later update m2 respository with the dependency
Yes, this is how it works.
The phases are executed in order and the installation into the local repository is the last one.
With external dependencies it's simple: before compiling anything Maven downloads them.
With inter-module dependencies it's more complicated. It's important to understand that Maven first runs all phases for the 1st module, then runs all phases for the 2nd module, and so on. So depending on which phase you call there either will be a JAR file or there won't be.
Maven will try to give you as "high-quality" dependency as possible, meaning:
if you run mvn install - this will put 1st module's jar into ~/.m2, then by the time 2nd module starts - it already has a JAR dependency waiting in the local repo.
if you run mvn package the JAR doesn't go to local repo, it stays in target/. Thus this target/xxx.jar will be used as a dependency.
if you run mvn test there won't even be a JAR. There will only be target/classes. So 2nd module's compilation & runtime will have directory with classes & resources in its classpath (no JAR).
PS: this may actually lead to real implications. When you run tests in module2 you may be reading resources of module1 and working with their file paths. And everything will work fine in case of mvn test. But once you start running at least mvn package there won't be files anymore - all resources of module2 will be in JAR and thus can be accessed only with getResourceAsStream().

Building Products with Maven

I'm fairly new to Maven and I'd like to use it to build a multi-module project.
Lets assume I have the following svn repository structure:
- /trunk/common-services/login-service
(.jar) [re-usable components]
- /trunk/services/mybusiness-service
(.jar)
- /trunk/webservices/mybusiness-rest
(.war)
- /trunk/products/myproduct
(pom) [issue mvn command here]
What I'd like to be able to do is to checkout and build the entire "product" from a single pom using a single mvn command (from a developers pov as well as a CI pov). It's safe to assume that I have the trunk checked out.
How do I do this using Maven? I've looked at the Maven reactor plugin, but I can't figure out how to use it correctly (if it is the correct plugin to use).
The reactor plugin assumes each module has its pom.xml.
For your use case, you would want to create a pom.xml for each module (login-service, mybusiness-service and mybusiness-rest). You would specify the dependencies in each of the modules. For instance, if your mybusiness-rest depends on login-service and mybusiness-service, you would specify these projects as dependencies.
You would have a pom.xml in /trunk which specifies each of the modules to be built. You can use the reactor features in this pom.xml to determine, when to build (or not build) specific modules.
Your developers and CI can build using this single pom.

Maven tries to download dependency despite it existing in local repository

I have an installed dependency in my local repository. The remote repository where the dependency came from is now down for some reason. When I try to compile the project Maven says that it can't resolve dependency. But why???
When you have these error, simply clean the _remote.repositories that indicate maven where the dependency comes from. You will find this file for each artifact inside your M2_REPO.
Maven will compare the local POM's timestamp (stored in a repository's maven-metadata file) to the remote. When maven does this depends on the updatePolicy that can be defined in your settings xml.
Either set this to never (discouraged) or skip this check (only when a remote repository appears to be down) by using the -o option (offline); then maven will not check remote repositories.

Maven adds class files of snapshot dependencies

on my Windows machine I do have several proeject that I build with maven. At the moment they are all in SNAPSHOT-State. When I build a project that relies on one of the other projects maven always adds the class files of the other projects to the jar.
If I build the project on my CI-Server this problem does not occur. Does anyone have an idea why maven adds the class files to my jar?
I'm using maven 2.2.1
When I build a project that relies on one of the other projects maven always adds the class files of the other projects to the jar.
This is not a default behavior and, if it happens, you're somehow telling Maven to do so. If you want to hunt potential discrepancies, check the effective-pom, the effective-settings, the active-profiles using the following goals on both machines:
help:effective-pom
help:effective-settings
help:active-profiles
Also double check how Maven is invoked on the CI machine (extra command line parameter, etc).

find dependencies in target/classes instead of local repository?

Summary: I'm looking for a way to instruct maven to search for dependencies in target/classes instead of jar in the local repository
Say I have 2 modules, A and B where A depends on B. Both are listed in a module S. Normally I need to run 'mvn install' in S. I'm looking for a way to run 'mvn compile' so that when A is compiled its classpath will contain ../B/target/classes instead of ~/.m2/repository/com/company/b/1.0/b-1.0.jar.
(my reason is so that i can have continous compilation without the need to go through packaing and installation, or, more exactly, use 'mvn scala:cc' on multiple modules)
I don't think that this is possible without horrible hacking, this is just not how maven works. Maven uses binary dependencies and needs a local repository to resolve them. So, the maven way to handle this is to launch a reactor build on all modules. Just in case, have a look at Maven Tips and Tricks: Advanced Reactor Options.
But, during development, can't you just import all your projects in your IDE and use "project references" (i.e. configure your projects to depend on source code instead of a JAR) like most Java developers are doing? This is the common approach to avoid having to install an artifact to "see" the modifications.
If this is not possible and if you really don't want to install artifacts into your local repository, then you'll have to move your code into a unique module.
i know this is annoying. which helped me here is definitely IDE support. eclipse and IntelliJ are clever to collect all dependencies once a maven-project import is done. even cross module dependencies are compiled live.