maven import scope and profiles - maven

i have a maven multi-module project:
root
commons
common-module
plugins
plugin
commons and plugins don't have the same parent, and are "standalone".
in commons-module i define 2 profiles, projectA and projectB. in each of these profiles i define properties, such as dep.version, dep1.version etc...
later i use these properties in dependencyManagemnt for the version part in the dependencies of "dep" and "dep1" section.
in plugins (who is parent for plugin) i have a dependency scope import on commons-module to obtain the list of dependencies.
when i build the plugin module, it doesn't seem to matter if i do -PprojectA or -PprojectB: maven says they don't exist. they do exist, but in commons module, which i import.
so the dependencies i get don't have the correct versions when i mvn dependency:tree
is what i'm trying to achieve possible, am i don't something wrong, is this a maven bug, or a none-supported feature? anyone got a clue?
thanks,
Nathan.

Import scope only imports the dependencyManagement, not the dependencies themselves. You still need to declare the dependency on the artifact, and then the version, and scope etc will be picked up from the dependencyManagement.
I don't think import will work for pluginManagment sections. The documentation you linked to only mentions dependencyManagement, and the only other mention I've seen is this unanswered question to the mailing list.

Dependencies aren't allowed to change the POM of modules that simply use those dependencies. It wouldn't be a safe thing to do. Imagine that you're adding another dependency to your project, and suddenly the build stops working because the dependency actually overrides some of your settings.
POM interpolation inherits settings only from ancestor projects, going up the <parent> chain.

You are trying to use the import scope with profiles. However, profiles are not activated transitively, so the different dependencies in your import-scoped dependency's POM aren't being activated.
It's probably not recommended, but you could have two different commons modules, and include the import-scoped dependency in profiles that refer to one or the other in your current project.

Related

Is there a way I can have the aspectj maven plugin ignore missing weave dependencies instead of failing the build?

I wrote an aspect library that auto-instruments traces and because most of the developers using this have multi-module projects, it would be nice if they could just configure the aspectj-maven-plugin for compile-time weaving in the parent pom.xml instead of each module's pom.xml. The problem is that not all modules require certain weave dependencies and as such I would like it if the plugin could ignore those missing dependencies when weaving those modules instead of failing the build. Is this even possible?
Configure plugin version and common settings in the parent's pluginManagement section, then simply add the plugin group ID and name to each module's plugins section where it is needed, optionally amending or changing the configuration. Adding a plugin to the parent POM even though not all modules use it, is simply wrong from a Maven perspective.

Is it possible to force a Maven plugin to be included in a project from a dependency of that project?

I have three Java projects. The first is an application, com.foo:foo-application:1.0.0, and the second is a module used as a dependency to that application, com.foo:foo-framework:1.0.0. The third is a Maven plugin authored by our team, com.foo:foo-plugin:1.0.0.
My intention is that any project, e.g. foo-application, which uses classes available in foo-framework must also validate that it has used those classes correctly, where said validation is enforced by foo-plugin.
Is there a way to enforce this behaviour within foo-framework's POM.xml, whereby any Maven module which declares it as a dependency in its own POM will have foo-plugin executed as part of its build lifecycle?
No (at least no way that I'm aware of).
when you declare a dependency on something, youre declaring a dependency on its output artifacts (and transitively their dependencies as optionally described in that artifact's pom.xml file). There's no place in a pom file to force anything on the build importing it - the build importing it may not even be a maven build.
it appears you may be able to do something similar via other tools though - for example checkstyle supports discovering rules from dependencies on the classpath (not exactly what you want and depends on users of your library running checkstyle configured just right)

JBoss Maven BOMs and transitive dependencies

I'm trying to use a number of the BOMs in the org.jboss.bom group to bring in the API stacks that are compatible with EAP 6.3.0. My understanding is, that's what they're for. But when I reference them (using 'provided' or even 'compile' scope), the dependencies don't become transitively available. Given that "compile" scope is used on the items inside the BOMs, Maven's documentation of the dependency mechanism seems to indicate that those items should be added to the classpath of my project. Yet I'm getting undefined symbols for the classes that should be brought in.
For example, in project P, I'm including org.jboss.bom.wfk:jboss-javaee-6.0-with-spring:2.4.0-redhat-2 with 'provided' scope, yet org.springframework.context.ApplicationContext is undefined in P.
This is all happening in JBoss Dev Studio 8.1.0.GA, if that makes a difference.
I figured out the solution myself by reading the Maven Dependency documentation in more detail.
Here's my take-away: you cannot depend on the Eclipse m2e plugin to see you through the Maven dependency weeds. Know when/how to use the <dependencyManagement> section of the POM (and when not to use it). Know in particular the specific invocation Maven needs when you want to use a BOM: import the BOM in a <dependencyManagement> section with <type> of pom and <scope> of import, and then in the "regular" <dependencies> section (not <dependencyManagement>) specifically call out the sub-artifacts you need from the POM, but omit the version. (It's all spelled out here.)
The intent of the BOM is not to allow you to mass-import dependencies by referencing only the BOM artifact; rather, it's to make sure the versions of dependencies are the right ones, as defined by the BOM.
Do not assume that Maven allows you to express things in logically/mathematically reduced terms. Find out how to please the beast, and do not rely on a wizard to figure this out for you. Read the Maven docs in detail, find out the recipes and follow them exactly.

How to handle two Maven submodules that share a code dependency

I have what I think is a fairly common setup. I have a project with two modules, each with its own pom.xml. Above that, I have a pom.xml for the project, which depends upon its submodules. The two submodules have a shared dependency, namely log4j. How should I deal with this dependency? Should I simply just have each submodule have log4j as a dependency, or should the higher level project module get involved, claiming it as a project dependency? If I have both submodules listing the dependency, will Maven be smart and only pull down log4j once, or will each submodule pull down its own private copy of log4j ? If the project module has the dependency, will the log4j package be available at the right time for the submodules? What would you do, or what have you done in this situation?
The best way to do this is with the dependencyManagement tag.
The dependency management section is a mechanism for centralizing dependency information. When you have a set of projects that inherits a common parent it's possible to put all information about the dependency in the common POM and have simpler references to the artifacts in the child POMs.
To summarize the effect, you put the tag in the parent pom and have the children refer to it. They don't refer to the version number though. The benefit is at any time you can update the version of log4j in the parent pom and all your child poms get the new version without modifying their poms.
You are able to set the dependency at the higher level project. This will cover the dependency for both modules of your project.
Source: This is what my team does in one of our projects.

Is declaring maven "dependencies" in pom.xml really necessary?

I need some verification of how Maven works.
How important is it for us to specify the project dependencies explicitly (<dependencies>) in pom.xml? Some said that it's necessary only when we need a specific version of that jar, otherwise Maven will be able to find the jar in your local / Maven's remote repository. However, I find that sometimes I could not build or package a Maven project without specifying/declaring the dependencies.
So.. is the declaration really necessary?
If your code just uses "plain" Java and does not depend on any other libraries you do not need to declare any dependencies (because you do not depend on anything other than the Java runtime).
In most cases you will use some 3rd party libraries - thus you have to declare them as dependencies in your project to let maven construct a valid classpath which lets your build work (transitive dependencies will be resolved automatically - as already mentioned).
Regarding to the specific version of a jar have a look at the Project Dependencies section of the "Maven: The Complete Reference" book provided by Sonatype. You have several options to declare the version you need (including version ranges).
Do not expect that the declaration
<version>1.2.4</version>
will force Maven to use that version. That is only meant as "allow anything, but prefer 1.2.4". If you need to force maven to use a specific version and nothing else you have to use
<version>[1.2.4]</version>
Yes, the dependencies are needed. Most plugins use them to construct the necessary classpath, or to determine what to include in the artifact. Maven is declarative - you are declaring what you need, not how and where to find them locally.
You need not to declare Transitive dependencies of a JAR. Other than that, everything must be declared. Here is a good read on how maven mananges dependencies. http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
You always need to specify the dependencies. Maven can't predict, which libraries you need. What you in most times don't need to specify, are additional Maven repositories. You need that only when you have libraries as dependencies, which are not contained in Maven Central.
What you also can eliminate in your projects, are the version numbers of your dependencies, if you have a parent POM, where the versions are specified.

Resources