I am not understanding what is the purpose of bom object? and I am working on Spring 3.2.8 version and with JBoss server, so which bom dependency I need to use? When I mention the following dependency in pom.xml:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>4.0.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Does the jar file gets downloaded into my Maven Dependencies?
What is the purpose of bom object?
Maven parent-child relationship is very handy for managing dependencies of multiple projects in a single place. However, Maven projects can have only one (direct) parent. So imports were introduced for dependency management to allow using several projects for managing your dependencies. With an import you can define a single dependency like this and get multiple dependencies managed - handy! Although you could import any project, BOM is a special project designed to be used for imports like this. Usually a BOM project will have very little defined besides dependencyManagement section, and will not have any unrelated dependencies, to avoid affecting your main project too much.
Which bom dependency I need to use?
BOM is not a requirement, you don't need to use either. Instead, you could define all managed dependencies in dependencyManagement section yourself. These can include Spring, JBoss and any other dependencies. BOM, however, simplifies this for you significantly. You can add as many BOMs as you want, so add both! But as #Jesper mentions, don't forget to use correct versions. When using multiple BOMs their order will matter if they both reference a common dependency.
Does the jar file gets downloaded into my Maven Dependencies?
Notice BOM is <type>pom</type>, not the default jar. So there's no jar to be downloaded. A single pom.xml file will be downloaded and read by Maven.
Related
I came across this dependency in one project pom.xml:
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-model</artifactId>
<version>3.3.9</version>
</dependency>
There is not much of detail on the page of maven-model project, but looks like it is just a definition (XSD) of pom schema and maven can obtain it without explicit declaration (as all other projects I've seen do not declare this dependency).
What could be the purpose of adding it explicitly?
It is a dependency which provides a Pojo model for maven files. You probably need it when you're writing a maven extension / plugin. I don't think it is useful for a "normal" project which happens to use maven.
I have a scenario as follows:
I am using maven as a build process. I am creating a web project in which I want to use a specific version of spring. This project also depends on a third party library which internally depends on different version of spring. I have a doubt that this will result two different versions of spring n class-path and unexpected behavior will be observed. I have few information which I wanted to get more clarification on.
Can I use maven BOM concept for this?
Can somebody explain with example how to achieve this?
Can somebody explain how do we make sure that third party wont behave abnormally if overall project depicts using a specific version using BOM?
If somebody can throw light on it and give a detailing reference, that would help me a lot.
Maven should know how to evict one or more of conflicting versions of an artifact.
However, you can influence that by simply excluding one of the transitively included dependency.
Example: the following code excludes the io.netty (transitive) dependency. In this way, you'd leave maven with the only other version as you decide/prefer.
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-client</artifactId>
<version>${hbase.version}</version>
<!-- The exclusion below makes sure that this specific version imported by hbase does not end up deployed -->
<exclusions>
<exclusion>
<artifactId>netty</artifactId>
<groupId>io.netty</groupId>
</exclusion>
</exclusions>
</dependency>
Regarding runtime behavior, you have to test and decide for yourself (that is if you aren't lucky to have your direct artifact that documents versions of its own dependency)
You can use the concept of BOM but this won't avoid the conflicting issue of libraries by itself. It's very common that projects have one or more library which depends on the same other with different versions. In this case, when you want to force some specific library version for that third party library you must explicit it in your POM by using < exclusion > markups. This is not an easy task, once that projects usually have many libraries. So you need a tool to provide you an easy way to visualize a dependency hierarchy of your project libraries. There are some IDE plugins for this. Some versions of Eclipse, for example, have the maven plugin included in it, which provide a Dependency Hierarchy view ( a kind of dashborad of libraries and their dependencies ). Once you detected a library which should not using other library dependency ( wrong version for example ), you go at the this dependency in the pom and use the exclusion markup adjust the dependency version. Using the tool will make this task very simple.
I'm fairly new to the Eclipse and Maven2 worlds. I'm struggling to comprehend how to add a Maven project dependency on Apache Jena in a simple way. Specifically, I'd like to add a dependency such as
<dependency>
<groupId>org.apache.jena</groupId>
<artifactId>jena</artifactId>
<version>${jena.version}</version>
</dependency>
And this would automatically pull in the modules(eg. jena-arq, jena-core, etc). However, adding this dependency results in a Missing artifact org.apache.jena:jena:jar:2.11.1 error. If I add <type>pom</type> to the dependency the error is gone but I do not get the jars in my project.
In any event, as I understand it, POM is more suited to project <--modules dependencies and what I'm really looking for is project --> lib archive dependencies.
How do I establish such a relationship? I considered simply replicating the dependency for each module in Jena since it's using a property anyway. However, it is possible, and Jena is a prime example, that not all modules in a project share the same version. For example jena-core is on 2.11.1 where jena-tdb is on 1.0.1 however jena-2.11.1 encompasses jena-tdb.
Thanks
See http://jena.apache.org/download/maven.html for details.
In brief:
<dependency>
<groupId>org.apache.jena</groupId>
<artifactId>apache-jena-libs</artifactId>
<type>pom</type>
<version>2.11.1</version> <!-- Set version -->
</dependency>
Note that it is type pom.
there is not a easy way do this.
you must define every dependency jar with special version.
I have a maven-java project (say Project A) with a parent defining modules in its pom.
I also have an external project (say Project B) that requires dependencies of two of the modules from Project A. For now, i have defined the dependency to pull each module individually.
When i replace these two with a dependency on the parent pom, it errors out on build. Is there some modification i need to make to my parent pom of Project A to make this work?
Can this be done in the first place?
Can this be done in the first place?
Declaring a dependency on an aggregating POM won't get the modules transitively. This is not going to work. It is possible to create a POM to group dependencies though.
For example, EHCache uses this technique. As mentioned in their documentation:
Maven Snippet
To include Ehcache in your project
use:
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.0.1</version>
<type>pom</type>
</dependency>
The net.sf.ehcache:ehcache artifact is precisely used to group dependencies (and is distinct from net.sf.ehcache:ehcache-parent).
References
The Maven Guide
3.6.1. Grouping Dependencies
Say I have two Maven dependencies defined in a project like below.
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.3.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mycompany.library</groupId>
<artifactId>mylibrary</artifactId>
<version>1.0.1</version>
<scope>compile</scope>
</dependency>
Then, within mylibrary, I also have a dependency defined as below.
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.3.1</version>
<scope>compile</scope>
</dependency>
When I package my project, I don't see xstream packaged within it. I think the project's xstream dependency scope, 'test' is overriding the mylibrary's xstream dependency scope, 'compile'.
In this kind of situation, what's the best way to include the xstream for the whole project so the submodule can have access to it when packaged within the project?
I've read Apache Maven website's explanation on Transitive dependencies, but I'm struggling to understand what it means, and also to find out the best practice in this situation.
This feels really odd to me, and if it's "feature", I think it is a really dangerous one.
Anyway, it's not a Maven bug and it's in the maven documentation here.
Regarding best practices on this issue, I haven't heard of any, but the safest way to proceed ought to be to entirely remove xstream from your pom, relying on the transitive dependency. Doing this will result in a build failure if the dependency to mylibrary is removed. This will act as a notification to you that you need to fix something. You won't silently loose required dependencies, and you won't silently have dependencies you no longer need.
On a side note, mvn dependency:analyze can be used to check for dependencies that are included but not used.
As mattb's answer says, declaring the dependency as test scope overrides the transitive compile-scoped dependency declaration, and as a result the dependency is not included in your packaged war.
If you only need the dependency in your tests because 'mylibrary' needs it to execute, you shouldn't declare the dependency at all in your project's pom. Let the transitive dependency resolution process handle it.
If your project does use the xstream jar directly, you can still rely on the transitive dependency, as you will need a compatible version for your project and 'mylibrary' to both run against the xstream jar. You should have unit tests that exercise the functionality, and if mylibrary changes version of xstream to an incompatible version, your builds should fail, and you can address the issue at that point.
In general I'd say you should try to avoid declaring dependency versions directly in multi-module projects. I declare the versions in a dependencyManagement section of a parent POM so that the child need only declare the groupId/artifactId. Alternatively, from Maven 2.0.9 onwards there is an additional dependency scope of import:
This scope is only used on a dependency of type pom in the section. It indicates that the specified POM should be replaced with the dependencies in that POM's section. Since they are replaced, dependencies with a scope of import do not actually participate in limiting the transitivity of a dependency.
So using import scope you can define your common dependency versions in a single POM, import the dependencies of that POM into your dependencyManagement section, and just declare the groupId/artifactId of the dependency in your other POMs.
By declaring your own dependency on xstream, and setting the scope to test, you are overriding the dependencies declared by mylibrary.
This is actually a Maven feature - it allows you to do things such as depend on a later version of a transitive dependency within your own project, and not end up packaging two different versions of the same artifact. For example, you might depend on version 1.2.15 of log4j, but because you also use libraryX which depends on log4j-1.2.14 - you wouldn't want both log4j-1.2.15 and log4j-1.2.14 to be packaged with your project.
If you actually want xstream to be packaged within your project, you should not be declaring the scope as test. In fact if you remove your listed dependency on xstream, things will work out as you like, since mylibrary has a compile dependency on it..
If you want it packaged, why are you declaring scope? If it is required at compile and execution time, shouldn't you leave the scope blank? If you did that, then you would only need
<dependency>
<groupId>mycompany.modules</groupId>
<artifactId>submodule</artifactId>
<version>1.0.1</version>
</dependency>
in your pom. Unless there is a reason to descope it during compile but not during packaging?