We have multiple maven projects depending on on our own common libraries.
When we upgrade a library it would be useful to quickly find out which projects have a dependency on the library (and might need to use the new version)
Obviously I can manually look in all the pom files or write a script to do it but this is less than ideal.
Are there any tools that provide this functionality. e.g. a hudson plugin, Nexus, artifactory etc?
EDIT:
Some clarifications:
I don't want to upgrade all projects at once. The regression testing and release effort makes this impractical and often unnecessary (even with automated testing and releasing). I just want a report showing me what may projects may need to have the library upgraded...
Many answers focus around the project itself flagging what version is used. Ideally the solution would work so that for a given library I can ask what uses this. This looks like what the Nexus issue below is talking about.
Hudson does something similar with automated downstream maven builds. I may look into extending this with a hudson plugin.
I know that albeit being a good tool for managing poms and jars, Artifactory has no such feature you're asking :(
You might want to check this StackOverflow question: Look for new versions of dependencies
Alternatively you might want to check Versions Maven Plugin. Among other things, it allows you to scan trough project's dependencies and produce a report of those dependencies which have newer versions available.
A quite usual practice is to declare all the versions in dependencyManagement of the parent module and reference dependencies without versions everywhere else. In this case you'll only need to update only one POM.
I solved this issue by using dependency version ranges to fetch the newest versions automatically.
<dependency>
<groupId>foo.xyzzy</groupId>
<artifactId>bar</artifactId>
<version>[1.0.0,2.0.0)</version>
</dependency>
It might make sense to use a version range such as [1.0,) to include the newest version after 1.0.
The trick to make this work is to have dev and prod profiles that include and exclude the snapshot repos for your commons and to use hudson to automatically build projects when a dependency is re-built.
Not exactly what you're asking for but the Dependency Convergence report might be helpful. Here are some examples.
Update: I'm aware that I'm not exactly answering the question with my suggestion but doing it the other way (finding all projects that reference a given artifact) would require gathering all POMs of all projects and I'm not aware of a solution currently offering such a referenced by feature (a corporate repository would be the perfect candidate to implement this though).
My search is over: http://www.sonarsource.org/sonar-2-1-in-screenshots/
Sonar now provides this.
Related
I've recently switched from Jersey 1 to Jersey 2 for some projects I work on. The biggest annoyance I've run across with Jersey 2 is that it uses HK2, which for some reason repackages standard Maven artifacts. To avoid potential annoying-to-debug issues, I try to avoid pulling in the same classes from different projects. I use the Ban Duplicate Classes Maven enforcer rules from the Extra Enforcer Rules dependency to break the build if this occurs.
According to the aforementioned Ban Duplicate Classes enforcer rule, switching to Jersey 2 has introduced the following conflicts between its artifacts and standard ones I was previously using:
hk2 Artifact Conflicting Artifact
org.glassfish.hk2.external:aopalliance-repackaged:2.3.0-b07 aopalliance:aopalliance:1.0
org.glassfish.hk2.external:bean-validator:2.3.0-b07 com.fasterxml:classmate:0.8.0 (used by org.hibernate:hibernate-validator:5.0.0.Final)
org.glassfish.hk2.external:bean-validator:2.3.0-b07 javax.validation:validation-api:1.1.0.Final
org.glassfish.hk2.external:bean-validator:2.3.0-b07 org.hibernate:hibernate-validator:5.0.0.Final
org.glassfish.hk2.external:bean-validator:2.3.0-b07 org.jboss.logging:jboss-logging:3.1.0.GA
org.glassfish.hk2.external:javax.inject:2.3.0-b07 javax.inject:javax.inject:1
My solution has been to exclude the standard artifacts from the dependencies that transitively pull them, and therefore use only the hk2 artifacts. I figure this is safer: I don't know what else the hk2 artifacts are pulling in that I might be missing if I were to exclude them instead (for example, the bean-validator artifact appears to be repackaging at least four artifacts). The downsides to this are that first, I a ton of exclusions peppering my dependencies that were bringing in otherwise innocuous API dependencies, such as validation-api. Secondly, my artifacts are now exporting HK2 repackaged dependencies, rather than the actual API classes I would prefer to be exporting.
Ultimately, my questions are:
Why does HK2 repackage everything? Is there some good reason for this?
What is HK2 actually repackaging, and can I just use the standard API versions instead? How would I figure this out? I've cloned the HK2 project, and I've had a bit of trouble figuring out where to begin to find this out.
Barring the actual answer to these questions, what would be a good forum for contacting the developers behind HK2 so I can ask the question directly? I've looked through the website, and while I've found some mailing lists, I'm not seeing anything obviously appropriate for asking this question.
HK2 runs in an OSGi environment for products such as GlassFish. Unfortunately most of the standard jars such as javax.inject, bean-validator and aopalliance do not come with proper OSGi headers. So hk2 needs to repackage them with OSGi headers so that they will work properly in that environment.
Also since GlassFish is the RI for Java EE there are certain legal requirements that are made about the availability of the source code, so some of the repackaging that is done is to satisfy the availability of source code requirements.
That being said, if you are NOT running in an OSGi environment it is safe to replace these jars with the standard versions (though I myself have not tried this)
I haven't downloaded spring in a while. I'm investigating gradle, but don't seem to have the hang of it yet, so i want to create a new spring framework project using java, Spring 4 and ant. I can't seem to find the place to download the binaries for Spring 4.
Are they just kicking ant developers under the bus?
Are they just kicking ant developers under the bus?
No. As Brian mentions, distribution zips are still available at http://repo.spring.io for those who have no other option. Ant users are encouraged to integrate Ivy into their build scripts to manage dependencies so that they will not need these dist zips. Ivy is capable of working against Maven-compatible artifact repositories to provide the same transitive dependency management benefits as Maven and Gradle do. Ant is a perfectly fine build solution for many folks, and we expect it will continue to be for some time. However, manually managing dependencies, i.e. downloading dist zips, storing jars on a network drive or checking them into source control is widely understood in the industry as a problematic approach.
We believe that the majority of Spring users are already using transitive dependency management solutions in one form or another. We continue to provide dist zips for those who have not yet been able to adopt this practice, but to be clear, it is intentional that we have not given those dist zips the first-class treatment on spring.io that they once had on springsource.org, because working with dist zips is simply an inferior way to manage an application's dependencies.
Spring is about helping application development teams eliminate unnecessary complexity. There are few things that can make developing an application more complex and frustrating than the "jar hell" that ensues from manual dependency management. Here are but a few examples of why this can be so painful:
Needing to be connected to the network drive where jars are stored (and thus, very often needing to be connected to the corporate VPN);
Or, in the case of jars being checked into the repository, having massive, unwieldy repositories to manage, typically resulting in many duplications of the same jars across different repositories;
Having no simple, universal and reliable way to (a) know what a dependency's version is and more importantly, (b) know whether that version of that dependency is compatible with all of the other jars in the application's dependency graph.
Maven, Gradle and Ivy are not a silver bullet for all dependency management issues, and naturally they come with their own complexity and learning curve. However, when given a choice, the vast majority of modern Java application developers agree that the benefits of using transitive dependency management outweigh their costs.
We hope that we've struck the right balance in our approach to guiding users how to consume Spring artifacts. We've shone the spotlight on what we (and most folks) consider to be best practices with dependency management by advertising Maven and Gradle syntax, but we've left the door to all comers by by continuing to publish distribution zips. We are however paying attention to feedback to make sure that this approach is in fact suitable for the majority of our users.
For additional information on this topic, see https://github.com/spring-projects/spring-framework/wiki/Downloading-Spring-artifacts.
And as a final note, we sometimes hear from folks that they need distribution zips because their company disallows access to public Maven repositories such as Maven Central (http://search.maven.org) or the Spring Repository (http://repo.spring.io). This is completely understandable, but the appropriate response to these constraints is not to keep development teams in the unproductive dark ages of manual dependency management. The correct solution is to stand up a private artifact repository within the corporate firewall. The leading contenders in this product space are JFrog's Artifactory and Sonatype's Nexus. We strongly recommend that any development team still forced into manual dependency management lobby their architecture teams to look into these products and adopt one of them. The benefits to productivity, build reproducibility, and indeed the ability for companies to effectively govern dependencies are dramatic.
Maven and Gradle are the preferred ways to use Spring Framework in your project, but dist ZIPs are still available on the official repository.
You can use the Maven config, go to any Maven repo, and download the JARs from there. For instance:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
</dependencies>
Tells me to look in /org/springframework/spring-context/4.0.0.RELEASE folder under any Maven 2 Repository. Using the example, I found this. You should be able to get all the JARs from there.
You can find the dependency information for Spring 4 here
From there you can download the binary jar and the jar with sources for manual dependency management.
I found two sources: the official download page here and OLEX.
This was after wasting lots of time trying to find the zip files via searches on the Spring site. There are no longer any direct download links there.
I have a system consisting of multiple web applications (war) and libraries (jar). All of them are using maven and are under my control (source code, built artifacts in Nexus,...). Let say that application A is using library L1 directly and L2 indirectly (it is used from L1). I can easily check the dependency tree top-down from the application, using maven's dependency:tree or graph:project plugins. But how can I check, who's using my library? From my example, I want to know, whether A is the only application (or library) using L1 and that L2 is used from L1 and from some other application, let say B. Is there any plugin for maven or nexus or should I try to write some script for that? What are your suggestions?
If you wish to achieve this on a repository level, Apache Archiva has a "used by" feature listed under project information
.
This is similar to what mvnrepository.com lists under its "used by" section of an artifact description.
Unfortunately, Nexus does not seem to provide an equivalent feature.
Now I suppose it would be a hassle to maintain yet another repository just for that, but then it would probably easier than what some other answers suggestions, such as writing a plugin to Nexus. I believe Archiva can be configured to proxy other repositories.
Update
In fact, there's also a plugin for Nexus to achieve the "used by" feature.
As far as I know nothing along these lines exists as an open source tool. You could write a Nexus plugin that traverses a repo and checks for usages of your component in all other components by iterating through all the pom's and analyzing them. This would be a rather heavy task to run though since it would have to look at all components and parse all the poms.
In a similar fashion you could do it on a local repository with some other tool. However it probably makes more sense to parse the contents of a repo manager rather than a local repository.
I don't think there's a Maven way to do this. That being said, there are ways of doing this or similar things. Here's a handful examples:
Open up your projects in your favorite IDE. For instance Eclipse will help you with impact analysis on a class level, which most of the time might be good enough
Use a simple "grep" on your source directory. This sounds a bit brusk (as well as stating the obvious), perhaps, but we've used this a lot
Use dependency analysis tools such as Sonargraph or Lattix
I am not aware of any public libraries for this job, so I wrote a customized app which does it for me.
I work with a distribution which involves more than 70 artifacts bundled together. Many times after modifying an artifact, I want to ensure changes are backward compatible (i.e. no compilation errors are introduced in dependent artifacts). To achieve this, it was crucial to know all dependents of modified artifact.
Hence, I wrote an app which scans through all artifacts under a directory(/subdirectories), extracts their pom.xml and searches (in dependency section of pom) for occurrence of modified artifact.
(I did this in java although shell/windows script can do this even more compactly.)
I'll be happy to share code on github, if that could be of any help.
One way that might suit your needs are to create a master-pom with all your maven projects. Then you run the following command on the master-pom:
mvn dependency:tree -DoutputType=graphml -DoutputFile=dependency.graphml
Open the generated file in yEd.
Used the instructions found here:
http://www.summa-tech.com/blog/2011/04/12/a-visual-maven-dependency-tree-view/
More interesting is probably: what would you do with this information? Inform the developers of A not to use library L1 or L2 anymore, because it has a critical bug?
In my opinion you should be able to create a blacklist of dependencies/parents/plugins on your repository manager. Once a project tries to deploy/upload itself with a blacklisted artifact, it should fail. I'm saying uploading and not downloading, because that might break a lot of projects. As far as I know, this is not yet available for any repository-manager.
One of the ways to approach this problem is outside Java itself : write an OS-level monitoring script that tracks each case of fopen() on the jar file under question! Assuming this is in a corporate environemnt, you might have to wait for a few weeks (!) to allow all using processes to access the library at least once!
On Windows, you might use Sysinternals Process Monitor to do this:
http://technet.microsoft.com/en-us/sysinternals/bb896645
On Unix variants, you would use DTrace or strace.
IMHO and also from my experience, looking for a technical solution for such a problem is often an overkill. If the reason why you want to know who is using your artifact(library) is because you want to ensure backward compatibility when you change an artifact or something similar, I think it is best done by communicating your changes using traditional channels and also encourage other teams who might be using your library to talk about it (project blogs, wiki, email, a well known location where documentations are put, Jour fixe etc.).
In theory, you could write a script that crawls though each project in your repository and then parses the maven build.xml (assuming they all use maven) and see whether they have defined a dependency to your artifact. If all the projects in your organization follows the standard maven structure, it should be easy to write one such script (though if any of those projects have a dependency to your artifact via a transitive dependency, things can get a bit more tricky).
I have a Java project, built with Maven, that aggregates several components, each one in its own Maven project. Any one of these components may evolve separately.
The structure of my project can be described as follows:
my-main-project that depends on:
my-component-1
my-component-2
etc.
Nowadays, all pom.xml are using "snapshot" versions, so, they are all using the "latest" version available in my repository.
But once I send a release version to my customer, I'm supposed to freeze the versions and make a TAG (or equivalent) in my source-control, so I can restore a previous state in case of maintenance.
So, my question is: should I change all pom.xml files before each release, give version numbers to the components, and tie everything with this dependency versions? Also, if I have many components (my project currenty has 30+ small subcomponents) would I have to renumber/reversion each one before each release? When a single component evolves (due to bug fix or enhancement), must I increase its version so that the changes do not affect pre-existing releases, right?
How people using maven generally handle this many-component versioning case?
Of course, I could just rely on my version-control tags to restore to a previous point-in-time and just tag every component on each release, but I don't like this approach, since the dependency versioning (with maven) gives me much more control and visibility about what is packaged, and relations of (broken-)compatibility and many more.
General Considerations
You may consider some relations between your components.
Are they really independant (each one vs each other) ? Or is there some kinds of relation ... some commons lifecycles ?
If you find some relationship between them, consider using maven multi-modules : http://www.sonatype.com/books/mvnex-book/reference/multimodule.html. In a few words, you will have a parent, with one version, and some modules (some jars .. in a way like Spring and its submodules). This will help you to reduce versions management.
You may consider using maven-release-plugin. It will help you to tag, build and deploy automatically your modules, dealing more easily with versionning and links with SCM and Repository.
Moreover, combine with multi-module it would drastically help you !
There is a lot of topic dealing with this on Stack Overflow.
I don't know if you already know that. I could explain it a lot further if you want, but you may have enough elements to search by yourself if you don't.
Straight Answers
So, my question is: should I change all pom.xml files before each release, give version numbers to the components, and tie everything with this dependency versions?
Yes you should. In Application Lifecycle Management follow the changes is REALLY important. So, as you could imagine, and as you point it out, you really should build and tag each of your components. It could be painful, but maven-realease-plugin and multi module (even with a Continuous Integration plateform) it could be easier.
would I have to renumber/reversion each one before each release?
For exactly the same reasons : yes !
must I increase its version so that the changes do not affect pre-existing releases, right?
Yes, you should too. Assuming you choose a common versionning like MAJOR.minor.correction, the first number indicate compatibilty breaks. Minor version would bring some breaks, but should not. Corrections whould NEVER affect compatibility.
How people using maven generally handle this many-component versioning case?
I cannot reply for every one, but my previous comments on release-plugin and multi-module considered as best pratices. If you want to a little bit further, you can imagine use more powerfull SCM (Clearcase, Perforce, ...), but maven integration is fewer, not "well" documented and community provide less examples than SVN or Git.
Maven Release Plugin
If you are using a multi-module pom.xml you should be able to do mvn release -DautoVersionSubmodules and have it do a "release" build of all your dependencies and remove the -SNAPSHOT versions and upload them to your repository. That is what the release plugin and its workflow exists solely to do.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
What are the main benefits of using maven compared to let's say ant ?
It seems to be more of a annoyance than a helpful tool.
I use maven 2, with plain Eclipse Java EE (no m2eclipse), and tomcat.
Supporters of maven believe that
Maven lets you get your package dependencies easily
Maven forces you to have a standard directory structure
In my experience
Figuring out package dependencies is really not that hard. You rarely do it anyway. Probably once during project setup and few more during upgrades. With maven you'll end up fixing mismatched dependencies, badly written poms, and doing package exclusions anyway.
Slow FIX-COMPILE-DEPLOY-DEBUG cycle, which kills productivity. This is my main gripe. You make a change, the you have to wait for maven build to kick in and wait for it to deploy. No hot deployment whatsoever.
Or am I just doing it wrong ? Please point me to the right direction, I'm all ears.
Figuring out package dependencies is really not that hard. You rarely do it anyway. Probably once during project setup and few more during upgrades. With maven you'll end up fixing mismatched dependencies, badly written poms, and doing package exclusions anyway.
Not that hard... for toy projects. But the projects I work on have many, really many, of them, and I'm very glad to get them transitively, to have a standardized naming scheme for them. Managing all this manually by hand would be a nightmare.
And yes, sometimes you have to work on the convergence of dependencies. But think about it twice, this is not inherent to Maven, this is inherent to any system using dependencies (and I am talking about Java dependencies in general here).
So with Ant, you have to do the same work except that you have to do everything manually: grabbing some version of project A and its dependencies, grabbing some version of project B and its dependencies, figuring out yourself what exact versions they use, checking that they don't overlap, checking that they are not incompatible, etc. Welcome to hell.
On the other hand, Maven supports dependency management and will retrieve them transitively for me and gives me the tooling I need to manage the complexity inherent to dependency management: I can analyze a dependency tree, control the versions used in transitive dependencies, exclude some of them if required, control the converge across modules, etc. There is no magic. But at least you have support.
And don't forget that dependency management is only a small part of what Maven offers, there is much more (not even mentioning the other tools that integrates nicely with Maven, e.g. Sonar).
Slow FIX-COMPILE-DEPLOY-DEBUG cycle, which kills productivity. This is my main gripe. You make a change, the you have to wait for maven build to kick in and wait for it to deploy. No hot deployment whatsoever.
First, why do you use Maven like this? I don't. I use my IDE to write tests, code until they pass, refactor, deploy, hot deploy and run a local Maven build when I'm done, before to commit, to make sure I will not break the continuous build.
Second, I'm not sure using Ant would make things much better. And to my experience, modular Maven builds using binary dependencies gives me faster build time than typical monolithic Ant builds. Anyway, have a look at Maven Shell for a ready to (re)use Maven environment (which is awesome by the way).
So at end, and I'm sorry to say so, it's not really Maven that is killing your productivity, it's you misusing your tools. And if you're not happy with it, well, what can I say, don't use it. Personally, I'm using Maven since 2003 and I never looked back.
Maven can be considered as complete project development tool not just build tool like Ant.
You should use Eclipse IDE with maven plugin to fix all your problems.
Here are few advantages of Maven, quoted from the Benefits of using Maven page:
Henning
quick project setup, no complicated build.xml files, just a POM and go
all developers in a project use the same jar dependencies due to
centralized POM.
getting a number of reports and metrics for a project "for free"
reduce the size of source distributions, because jars can be
pulled from a central location
Emmanuel Venisse
a lot of goals are available so it isn't necessary to develop some
specific build process part contrary
to ANT we can reuse existing ANT tasks
in build process with antrun plugin
Jesse Mcconnell
Promotes modular design of code. by making it simple to manage mulitple
projects it allows the design to be
laid out into muliple logical parts,
weaving these parts together through
the use of dependency tracking in pom
files.
Enforces modular design of code. it is easy to pay lipservice to modular
code, but when the code is in seperate
compiling projects it is impossible to
cross pollinate references between
modules of code unless you
specifically allow for it in your
dependency management... there is no
'I'll just do this now and fix it
later' implementations.
Dependency Management is clearly declared. with the dependency
management mechanism you have to try
to screw up your jar
versioning...there is none of the
classic problem of 'which version of
this vendor jar is this?' And setting
it up on an existing project rips the
top off of the existing mess if it
exists when you are forced to make
'unknown' versions in your repository
to get things up and running...that or
lie to yourself that you know the
actual version of ABC.jar.
strong typed life cycle there is a strong defined lifecycle that a
software system goes thru from the
initiation of a build to the end...
and the users are allowed to mix and
match their system to the lifecycle
instead of cobble together their own
lifecycle.. this has the additional
benefit of allowing people to move
from one project to another and speak
using the same vocabulary in terms of
software building
Vincent Massol
Greater momentum: Ant is now legacy and not moving fast ahead. Maven is
forging ahead fast and there's a
potential of having lots of high-value
tools around Maven (CI, Dashboard
project, IDE integration, etc).
Figuring out dependencies for small projects is not hard. But once you start dealing with a dependency tree with hundreds of dependencies, things can easily get out of hand. (I'm speaking from experience here ...)
The other point is that if you use an IDE with incremental compilation and Maven support (like Eclipse + m2eclipse), then you should be able to set up edit/compile/hot deploy and test.
I personally don't do this because I've come to distrust this mode of development due to bad experiences in the past (pre Maven). Perhaps someone can comment on whether this actually works with Eclipse + m2eclipse.
Maven is one of the tools where you need to actually decide up front that you like it and want to use it, since you will spend quite some time learning it, and having made said decision once and for all will allow you to skip all kinds of doubt while learning (because you like it and want to use it)!
The strong conventions help in many places - like Hudson that can do wonders with Maven projects - but it may be hard to see initially.
edit: As of 2016 Maven is the only Java build tool where all three major IDEs can use the sources out of the box. In other words, using maven makes your build IDE-agnostic. This allows for e.g. using Netbeans profiling even if you normally work In eclipse
Maven advantages over ant are quite a few. I try to summarize them here.
Convention over Configuration
Maven uses a distinctive approach for the project layout and startup, that makes easy to just jump in a project. Usually it only takes the checkount and the maven command to get the artifacts of the project.
Project Modularization
Project conventions suggest (or better, force) the developer to modularize the project. Instead of a monolithic project you are often forced to divide your project in smaller sub components, which make it easier debug and manage the overall project structure
Dependency Management and Project Lifecycle
Overall, with a good SCM configuration and an internal repository, the dependency management is quite easy, and you are again forced to think in terms of Project Lifecycle - component versions, release management and so on. A little more complex than the ant something, but again, an improvement in quality of the project.
What is wrong with maven?
Maven is not easy. The build cycle (what gets done and when) is not so clear within the POM. Also, some issue arise with the quality of components and missing dependencies in public repositories.
The best approach (to me) is to have an internal repository for caching (and keeping) dependencies around, and to apply to release management of components. For projects bigger than the sample projects in a book, you will thank maven before or after
Maven can provide benefits for your build process by employing standard conventions and practices to accelerate your development cycle while at the same time helping you achieve a higher rate of success. For a more detailed look at how Maven can help you with your development process please refer to The Benefits of Using Maven.
Maven is a powerful project management tool that is based on POM (project object model). It is used for projects build, dependency and documentation.
It simplifies the build process like ANT. But it is too much advanced than ANT.
Maven helps to manage-
Builds,Documentation,Reporing,SCMs,Releases,Distribution.
- maven repository is a directory of packaged JAR file with pom.xml file. Maven searches for dependencies in the repositories.
I've never come across point 2? Can you explain why you think this affects deployment in any way. If anything maven allows you to structure your projects in a modularised way that actually allows hot fixes for bugs in a particular tier, and allows independent development of an API from the remainder of the project for example.
It is possible that you are trying to cram everything into a single module, in which case the problem isn't really maven at all, but the way you are using it.
This should have been a comment, but it wasn't fitting in a comment length, so I posted it as an answer.
All the benefits mentioned in other answers are achievable by simpler means than using maven. If, for-example, you are new to a project, you'll anyway spend more time creating project architecture, joining components, coding than downloading jars and copying them to lib folder. If you are experienced in your domain, then you already know how to start off the project with what libraries. I don't see any benefit of using maven, especially when it poses a lot of problems while automatically doing the "dependency management".
I only have intermediate level knowledge of maven, but I tell you, I have done large projects(like ERPs) without using maven.