Monthly Archives: March 2009

Dirty Tree – Resolved Tree – Resolved Graph


March 31, 2009 By oleg

Notions of Dirty Tree, Resolved Tree and Resolved Graph are floating around the resolution process. Here is the clarification – what is what:

mercury-trre-graph-difference

Maven 2.1.0 Released


March 22, 2009 By John Casey

We’re pleased to announce the release of Maven 2.1.0. If you’ve been staring longingly at version 2.1.0-M1 for the last few months, but couldn’t quite get up the nerve to try a milestone release, here’s your chance! Version 2.1.0 builds on the unprecedented stability of 2.1.0-M1, fixing the one or two bugs that were found in that release and adding some exciting new features. Some of these features include:

  • Obfuscated server passwords in the settings.xml (MNG-553)

This feature allows you to encrypt the passwords in the <servers/> section of your settings.xml, to keep them safe from prying eyes. To get started, see the Maven Mini-Guide to Password Encryption.

Tips for using encrypted passwords can also be found in the command-line help for Maven, mvn -h:

Options:
   […]
  -emp,—encrypt-master-password    Encrypt master security password
  -ep,—encrypt-password            Encrypt server password
  • Improvements to the Ant-based mojo support that bring up to feature parity with the maven-antrun-plugin (MNG-3971)

FINALLY, we have support for mojos and plugins written in Ant that’s every bit as good as the Ant support from the maven-antrun-plugin. All of the implied classpaths and innate expression-evaluation capabilities are now available to plugin developers who choose to use Ant.

  • Parallel resolution of artifacts (MNG-3379)

For those of you whose projects download the entire Internet when they build, you’ll probably be interested in parallel artifact resolution. This new feature allows up to five different artifacts (from different groupIds, initially) to be resolved at the same time, thereby shortening total build time in many cases. For more information, see the section “Configuring Parallel Artifact Resolution” in the Mini-Guide to Configuring Maven.

  • New build mode that mimics Make (MNG-2576)

If you’ve ever worked on a large project that contained many interdependent modules and wished you could build only the subset you’re currently focused on fixing, you should take a look at Maven’s new Make-like build modes. Using these modes, you have the ability to build dependency modules contained within the same multi-module build as the current project; to resume a failed multi-module build; and to rebuild all of the projects that depend on the current project. In short, this feature integrates directly into Maven’s core the capabilities found in the maven-reactor-plugin.

Tips for using the new Make-like build modes can be found in the command-line help for Maven, mvn -h:

Options:
   […]
   -amd,—also-make-dependents       If project list is specified, also
                                     build projects that depend on projects on the list
   […]
   -rf,—resume-from                 Resume reactor from specified project
   […]
   -am,—also-make                   If project list is specified, also
                                     build projects required by the list
   […]
   -pl,—projects                    Build specified reactor projects
                                     instead of all projects

You can also find the design document for these build modes here.

Migrating from Artifactory to Nexus


March 19, 2009 By Jason van Zyl

nx-big_large1When we interact with customers, we frequently encounter a department that has started using Artifactory and, while they are keen on using Nexus, it’s not very easy to migrate from Artifactory and configure Nexus as a drop-in replacement. We noticed this pattern, and decided to create a Nexus Migration Plugin that will allow existing Artifactory users to take an Artifactory backup ZIP and restore all groups, repositories, users, and permissions to a Nexus instance. In this post, I’ll walk you through the process, and I’ll point you at the new Appendix we added to the Nexus book that covers the Nexus Migration Plugin. Continue reading

A tour of the Nexus repository internals


March 15, 2009 By Tamas Cservenak

As part of the Nexus 1.3 release we revamped internals which makes for some interesting feature possibilities. Let’s take a look at what’s now available in the Nexus system.

How the repository system works in Nexus

Nexus 1.3 can now consistently handle all repository types (hosted, proxy, group, virtual) in the same way. We made changes to the repository model to handle all future Core and 3rd party Repository implementations by creating an API that will allow us to support alternative repository formats (p2, GEM, RPM) in a common way. Here, I will show you how to detect what sort of Live Repository instance you are dealing with.

Live Repository instances can describe their capabilities. They do it in future proof way, but let me explain few concepts first.

All repository objects are handled in the Nexus Proxy Core in same way. But, you are able to extend Nexus even by adding your new Repository interface implementation, and it will be still usable: you will be able to create instances of your repository using the same UI, and Core will handle those repositories in transparent way.

A Repository in Nexus has two orthogonal properties: ContentClass and RepositoryKind (naming was always my weakness, ask Brian!).

ContentClass describes the content of the repository. For you Maven users, it could be understood a layout in Maven World. Content classes supported in the core are: maven1, maven2. But, nothing stops you from adding new content classes, like P2, eclipse-update-site, etc. One key method exists on ContentClass:

public interface ContentClass
{
    String getId();
 
    boolean isCompatible( ContentClass contentClass );
}

As you can see, a content class can say it’s “compatible” with another content class. The reasoning for this is simple: you could have two different Java implementations for Maven2 Repositories for example. Both of them would hold Maven2 repositories with the standard maven2 layout, but they would be completely different implementations! Even then, you want to be able to group them together, right? So, they must have “compatible” content classes. The grouping is the most obvious operation that relies on ContentClass, but they are important in other places too, like virtual repositories. A virtual repository expects a ContentClass C1 as master repository, and “emits” a ContentClass C2. It does not have any expectations the class should only implement the Repository interface! It is simply a “conversion” between the C1 and C2 content classes.

The RepositoryKind is more a programmatic reflection. The RepositoryKind is for runtime inspection of live Repository instances.

public interface RepositoryKind
{
    Class getMainFacet();
 
    boolean isFacetAvailable( Class f );
}

Since Nexus 1.3 handles all repositories in same way there are no longer any difference in API to get at groups, virtuals, or hosted repositories. They are all unified. But how do you make the distinction then between a group and a hosted repo? Or how to discover is a Repository instance reference is a ProxyRepository? Simple: just ask the repository, and it will tell you.

repository.isFacetAvailable( GroupRepository.class );

And what about programmatic reflection? Well, there is one big exception: the DefaultRepository class. Despite it’s name, it is an abstract class, and serves as common ground for all simple repository implementations (those are the hosted and proxy repositories with potentially different content classes. Core contains only Maven2 repositories, but that will change soon). For that reason, this implementation is like a chameleon: when set up to be a proxy repository, it will be proxy repository even if the Java implementation does implement the ProxyRepository interface (hence, the plain Java reflection would lie to you)!

repository.getRepositoryKind().isFacetAvailable( ProxyRepository.class) will be TRUE if proxy repository.getRepositoryKind().isFacetAvailable( HostedRepository.class) will be TRUE if hosted repository.getRepositoryKind().isFacetAvailable( GroupRepository.class ) will be always FALSE …

What’s the reason for doing these acrobatics? Well, if you look at the sources, the hosted repository implementation is 100% contained in the “proxy” repository (the proxy does a little bit more when doing retrieve, that’s all).

And finally, when you find out what kind of repository instance you have, what should you do then? Simple:

if ( repository.getRepositoryKind().isFacetAvailable( ProxyRepository.class) )
{
    ProxyRepository p = repository.adapt( ProxyRepository.class );
}

Actually, you can adapt and the result will be null if not adaptable.

So, as you see, currently the only implementation that uses the runtime adaptable RepositoryKind is the DefaultRepository class, which is actually the base class for simple repositories. Simple repositories are hosted and proxy types. Those two kinds of repositories are only ones that have actual content. The composite repositories, like group, and virtual have no content. Groups are just an aggregated view of member repositories, while virtual is a handful of links pointing to the master repository.

And finally, after having this slightly complex taxonomy, it is not the end. Nexus is extensible regarding Repository implementation. Just watch us in the future!

The repository type registry

Yes, having all capabilities stated above available at runtime is nice, but how do you detect the available types of Repositories in Nexus? And also make that too future proof? Here comes the RepositoryTypeRegistry to make picture complete. Just like RepositoryRegistry says in its name it is a registry for live repository instances, offering various handy methods to get a hold of them. The RepositoryTypeRegistry here does the same, but for type discovery (think about new Repository types contributed by a Nexus Plugin).

The RepositoryTypeRegistry offers some basic methods to discover all available Repository implementations that are available to Nexus.

Actually, it is already used in Nexus. Nexus Pro already has P2 repository support. And you know what? Just throw in the P2 Nexus Plugin to existing Pro instance, and your drop down menus of the same UI elements you had before will get populated with new values. The same dialogs, like Repository Edit, Add New Repository, etc… will be used in the same UI to manage that new, plugin contributed Repository implementation. Neato! An entirely pluggable repository management system!

What other repository features are there?

We’re just scratching the surface here but we’ll explain a couple more prominent features. Nexus supports links (a la Linux symlinks) which let you do exactly the same things you are able to do on Linux file systems. Actually, the Maven1-to-Maven2 and Maven2-to-Maven1 virtual repositories are exactly built using solely links. Links do not have any content hence, no content duplication, as we promised. Naturally, when accessing Nexus over it’s Proxy API, you can use links even in your everyday repositories.

Another feature introduced is what we call a dynamic file. Let’s say, you want to make a file accessible somewhere in your repository. But, instead of using Nexus simply for storage and have the file updated every time it’s content changes, you want to make it’s content dynamic: to have its content pulled from somewhere else, from any underlying source you want.

Using dynamic files, you can decorate your repositories (and groups and shadows) any way you like. All you need to do is provide the component that will create the needed content, point it at the dynamic file, and simply store it just like you would with any other file in Nexus.

Oi! And what about Maven Archetypes?

A new OSS Nexus plugin is available called the nexus-archetype-plugin. The plugin is documented on the wiki.

In short, the Nexus Archetype Plugin will examine the content of your repositories, find all your Archetypes and an publish Archetype catalog on-the-fly. Yes, on-the-fly, so just deploy an archetype to your hosted repository, and it will be available in catalog right away.

Moreover, the plugin will automatically aggregate the catalog all the catalogs so you can have a repository group with a number of hosted repositories which contain Archetypes and they will all be available from what appears to be a single catalog available at the group URL. This uses the dynamic file capability in Nexus, very cool!

Have fun!

Maven Virtual Versions: Let's Fix this Mess!


March 12, 2009 By oleg

mavenMaven introduced a very useful idea – “virtual” versions: SNAPSHOT, LATEST, RELEASE. While this is an interesting and powerful feature, I’ve found that people still don’t have a firm grasp of how virtual version work and of some of the problems with SNAPSHOT versions. Depending on how you use and/or understand it, this feature can cut both ways. In this post, I take a closer look at Maven’s Virtual Versions and try to provide some clarity and definition. Continue reading