Programmatically Downloading Maven Articats (Aether vs. - ivy

I would like to write a small application which downloads an artifact and its transitive dependencies from an m2-format repository.
There are two obvious choices for this; Eclipse Aether or Apache Ivy's API.
Are there any considerations I should make when picking between the two options?

Related

How does Maven make it easy to manage Jar files?

While reading about Maven I came across the line below.
A very significant aspect of Maven is the use of repositories to
manage jar files across different projects.
But, to be frank, I completely disagree on this: Maven requires a lot of knowledge of it, a lot of time to resolve issues related to it, requires a repository, etc.
Please tell me how Maven manages Jar files. If it's the responsibility of the developer themself to specify what jars (with versions) to use, then how does Maven makes it easy to work with, or manage, Jar files?
Maven has a lot of benefits with respect to managing dependencies.
It downloads dependencies you specify from a trusted location (the
Maven Central repository) Dependencies don't need to be stored in
revision control, which saves space
It helps managing different versions of dependencies, which makes builds reliable and reproducible (specifying the same dependency in
different projects guarantees that both projects use the same
dependency)
It manages the inclusion of transitive dependencies for you (adding
a dependency to your project also adds all of that dependency's
dependencies, and their dependencies, and so on)
It manages the exclusion of conflicting versions of transitive
dependencies (if two of your dependencies rely on two different
versions of another dependency, only one version is used. You can
specify which one)
It makes your projects (local and remote) available to one another
to use as dependencies (if a module that you're developing on your
machine depends on another module you're developing on your machine,
you can declare that dependency, and Maven will include the built
version of one module when building the other)
In my opinion, there may be 2 scenarios where the overhead of Maven (yes, there is a steep learning curve compared to e.g. Ant) pays out:
Manage the versions of libraries in use
Manage the resulting libraries of your development
Manage versions of libraries
With Ant, you normally include the used libraries somewhere in a lib folder, and it depends on the good work of your architect, if the source of the libraries is known 3 or 5 years later. Maven helps managing that by providing a place for dependent libraries. There you may exactly fix the version you want to use, and the whole setup and retrieval will be done for you.
Manage resulting libraries
If you want to share your work with others in your company, a repository of shared libraries is the best thing then to have. By using Maven, you are able to deploy new versions to that repository, and others may use them then.
Caveat: You may use Ivy to do the dependency management only, if that is what you want to do.

Need presentation materials for convincing a customer to use Maven

My customer needs a more organized inventory of all 3rd-party libraries (such as JAR files) that are used in production for their projects. I am involved with a number of their Java-based projects. Their inventory has not been consistently maintained in the past and the time has come to account for all the libraries that are currently being used (there are quite a few!) and to enforce a structured process for introducing new libraries into the build environment.
I have tried pitching the idea of using Maven and Artifactory in their build process to leverage those tools' ability to manage a repository of binary libraries and handle transitive library dependencies. The customer is resistent to the suggestion because they think it will create more work for them to maintain an Artifactory server and learn the basics of Maven.
Currently, their Java projects are all built using Ant scripts. Transitive dependencies are largely managed by trial-and-error. The inventory of libraries currently in use is maintained by hand and the binaries are stored in a Subversion repository. The customer recognizes that this needs to be improved, but the current suggestions for improvement involve more ad-hoc "manage it by hand" approaches.
I want to convince the customer that a combination of Maven and Artifactory is a viable off-the-shelf solution for their Java library management needs. Can anyone direct me to literature/materials that I can use to create a presentation for my customer on the features and strengths of Maven and Artifactory?
Any other arguments/suggestions/etc that would assist me in this would also be appreciated.
I want to convince the customer that a combination of Maven and Artifactory is a viable off-the-shelf solution for their Java library management needs.
As pointed out in a comment, your customer doesn't necessarily need to fully adopt Maven to benefit from dependency management, you could adapt the existing ant scripts to use the Maven Ant tasks or Ivy. This might be less scary and already remove some pain.
Regarding the way Maven manages dependencies, I would simply explain that:
An artifact is identified by coordinates (groupId, artifactId, version).
This allows to store store them using a standardized directory structure (a repository)
A dependency is more that a JAR: it's a JAR with a POM which enables things like transitive dependencies resolution.
And the benefits of such a dependency management solution are:
no mess with dependencies, they are uniquely identified (no more "what version is that?" syndrom)
no more binary data in the VCS (faster checkout, less space)
easier reuse of artifacts between projects (no more jars sent by email)
easier management with transitive dependency resolution
And because you don't want to rely on public repositories, because you need to store your own artifacts, you need an enterprise repository. My personal choice would be Nexus:
because it's file based (unlike Artifactory, and I don't want to put my artifacts in a database)
because it's simple to install/use
because it's easy to administrate
Here are some resources about Nexus (sorry, I just don't use Artifactory):
Should we use Nexus or Artifactory for a Maven Repo?
Ning’s Migration from Artifactory to Nexus Professional
From Apache Archiva to Sonatype Nexus
And just in case, here are some presentation material about Maven:
Several presentations by Arnaud Héritier.
Maven 2.x by Jason van Zyl.
Maven 2.0 - Improve your build patterns by Vincent Massol.
3.5. Core Concepts in the Maven Definitive Guide

Best practice on how to configure two local maven directories for continous integration with Hudson

I use Hudson as our build server. WE have a very large project that is devided into several maven based projects. There are several dependencies between the artifacts of these projects. Currently we don't version the code good enough so that we need two maven repositories to manage the dependencies correctly.
My question is how to setup the two local repositories? I came up with two options:
I have two maven installation where each has it's own repository. In Hudson I can configure the two repositories and can choose whichever I want on the job.
I have one maven installation but two different config files. In this case I need to provide which config file to use within every job. The disadvantage is, that this information is displayed only if I hid the advanced button for the maven configuration within the job.
Are there any more options that I missed? What would you choose and why. The criteria is, that it should be easy to configure and easy to verify, even for someone who has little to no experience in configuring Hudson.
My suggestion would be to define the different repositories in different profiles either in settings.xml of the hudson server (if you dont want it in the development environment), or in a parent pom for your projects. And then activate the profile you want at build time on hudson. I am suggesting this one because it is independent of your maven installation, so you do not have to worry about your custom configs when upgrading maven...

Should I migrate from Ant to Maven?

I am working on a fairly large project (with a number of modules, a bunch of external libraries etc.) and we are now considering switching from Ant to Maven. I understand the differences between the two, but I am not convinced that it is really worth spending time converting the project layout, setting up all the dependencies, teaching developers and configuration managers doing things "the new way" etc.
There are a lot of resources on the web describing how to migrate from Ant to Maven, but I haven't found that many that say why :-)
Before changing your build system, ask yourself (and the group) why you're changing? If you're changing just because Maven is the "new thing", don't. If you actually see a technical reason to migrate, do it.
In general, unless there's a major compelling reason to do so (new capabilities or much simpler management), I'd say stay with what you have for the current project, but consider Maven for future projects.
Have you read chapter 1 of "Maven, the definitive guide"? In particular, 1.7 Comparing Maven with Ant has an interesting discussion.
I agree with the other answers that advise caution. Maven has strong points, but nothing that can't be done by an Ant build process:
dependency management: Ant has the Ivy subproject, which can interact with Maven repositories.
convention over configuration: you can also do that with Ant, it's just a matter of establishing the rules and enforcing them.
build lifecycle: same as above, you can enforce a convention over the tasks exposed by each build.
build logic reuse (Maven plugins): you can also achieve that in Ant with macrodefs and task libraries.
The thing is, with Maven you get these features out-of-the-box, while with Ant you need a rock-solid build, a very strict set of rules and a way to enforce them (for instance, make sure that everyone follows the conventions when they create a new subproject, that they reuse the existing blocks instead of doing everything from scratch, etc.).
Personally, I would see how well the existing process addresses the issues above: how are dependencies managed, is there a central repository? Are the project structures uniform (when I checkout a project I don't know, how long does it take to figure out how to build it)? Is there some form of build logic reuse, or does each project reinvent the wheel? Which of these features are needed?
Then I would try to balance the cost of adding the missing features to the existing Ant script, against the cost of migrating to Maven (if you don't know Maven, that also includes the cost of learning it).
In any case, I suggest you build a small Maven prototype (5 to 10 projects) illustrating the common cases in your build. You can test a lot of Maven's features with dummy projects containing little java logic (use the archetype plugin to generate them).
Before Maven we were checking dependency libraries (typically third-party, open source variety) into source control - so that we could insure our components compiled and got packaged with the precise versions intended.
Now with Maven in place, we're relying on artifact repositories to hold those versions and we let our pom.xml dependency declarations be the official means of defining version dependencies. This has proven to be a simplifying approach that makes project organization in version control repositories (and their Hudson build projects) much easier to devise. Our local artifact repository is under backup policy along with our source control repositories. It's nice to use the Maven tools to go and search and specify a needed library version. We also use parent pom files to specify dependencies that other project poms inherit by default. So if you want all projects to use the same log4j version, then that is specified in one place in the parent pom file. (But any project can at anytime override and specify a specific version instead of just accepting the default from the parent pom.)
Here is the secret to a successful adoption of Maven:
Use Maven project build approach for
your new greenfield projects
Modify existing legacy projects that
use ant build.xml files to incorporate Maven task
for managing depenedencies (a hybrid
approach)
The benefit is that you can then get all of your projects under Maven dependency management, which is of course it's greatest benefit.
The nice thing about the Maven task for ant, where you specify all dependencies in a pom.xml file, is that it involves just modest modification of the existing ant build.xml file to incorporate Maven for this. From the ant file's perspective, Maven is just a means for defining classpath definitions, which are subsequently used by the various ant build task.
The Maven scope classifier of dependencies can be utilized when defining classpaths such that a suitable classpath can be set for compiling, running unit test, packaging, et al. Other definitions in the pom can also be accessed as ant property definitions.
A lot of existing ant build files are rather complex. It can be a formidable undertaking to convert such projects to a full Maven build process. This hybrid approach of having Maven manage all the dependencies and leave the bulk of the ant build.xml file as is, is most pragmatic.
First, like I'm sure a lot of people will mention, Ant and Maven are not exactly intended to solve the same goals. Since you said you understand what each provides, I won't get into the details of that, so suffice it to say that Ant lets you define the details of how to build individual components, while Maven manages the dependencies between components plus Maven lets you define a complete project build cycle from compile through test and deploy in a programmatic way.
I've used Maven on a couple projects in the past, and I just started using it on another one recently. There are plenty of articles on the net that compare Ant and Maven, so you can look at those, but from my experience, its always worthwhile to consider how you can improve a project. Dependency management and build lifecycle are two important aspects of any large project, and Maven helps in both those areas. If you already have a good build system in place using ant, and your dependencies are kept in a easy to access central location, and you don't plan on extending your build process to include any more advanced build management, then maybe you should stay with what you have.
On the other hand, if you want to use a continuous integration server like hudson or an artifact repository like nexus, then moving your project to maven can really help with build efficiency and automation. You probably would like maven in those situations because the full cycle from dependency to build to artifact can be achieved using those types of tools and you'll be able to better control your builds and releases. On my current project we have many modules and dependencies, like you mention. Migrating to maven so we could use hudson and nexus really helped because we could drop all those 3rd party jars into a nexus repository and stop having to check them into version control or email them around. Also, builds were out of hand because the CM people had a build plan as a document that they would sometimes follow, but making that part of your project (i.e., the pom.xml) defines how you are supposed to build and lets you enforce it. Maven is the glue that holds all of those things together.
In the end, its a matter of how long you expect the project to last, how good your process is now, whether you want to clean up your dependencies, whether you want to enforce your build plan, and whether you want to have the option to use continuous integration and artifact management. If you any of those things, Maven is a strong candidate.

Is this the right approach for structuring codebase?

We have a Java codebase that is currently one Web-based Netbeans project. As our organization and codebase grows it seems obvious that we should partition the various independent pieces of our system into individual jars. So one Jar library for the data access layer, one for a general lib, one for a specialized knowledge access, etc. Then we'd have a separate project for the web application, and could have one for a command line tools app, another web app eventually, etc.
What is the recommended practice for doing and managing this? Is it Maven? Can it all be effectively done with just Netbeans alone by simply creating individual projects and setting the dependecies of one project on the jar files of the others?
I'd agree with SteveG above on using Maven2 to help you modularise your code base, but I'd use Nexus as the local repository for Maven instead of Archiva. The guys at Sonatype also have an excellent (free html/pdf) book on how to use Maven, Nexus, and integrate it into IDEs.
Be careful on how you decide to partition up your projects, though. There's no sense in over-complicating your dependencies just for the sake of it.
I would definitely say check Maven(2) out. It is very good for doing this sort of thing. You can define individual models and version then very easily. Netbeans also does a decent job of integrating with.
Also I suggest you set up Archiva which will let you be dependent upon binaries of other artifacts that your company generates internally. This also acts as a proxy and will keep a local copy of any external dependencies your projects might have so its very quick to get the new versions internally.
I would create ant scripts to build the pieces and for deployment. Then you are not depending on your IDE for build/deployment.
It sounds like your code is getting to the point where you're graduating from the WAR approach and have entered into the EAR level.
An EAR is just another archive that contains all the other JARs and WARs that get combined to create an application. There are four types of modules that can reside inside it, Web, EJB, Connectors and Utilities. Most people only use Web and Utilities so they go with using the WEB-INF/lib approach.
But if you're starting to get a lot of interdependencies what you do create an EAR project and make your web project a child of it. Each Utility JAR which is just straight Java code used by other modules also becomes a child of the EAR. Finally in each of your projects there should be a META-INF/manifest.mf file that just has the name of the JARs that JAR/WAR depends on.
I'm an eclipse guy and most of this gets taken care of for you in eclipse, but I'm sure netbeans has very similar functionality.
Now the only problem is that you have to use a full Java EE server to deploy an EAR so I don't think you can use Tomcat if that's what you're currently using.