Skip to end of metadata
Go to start of metadata


When the developer executes a Maven plugin (written in Java) from the command line, the Maven framework resolves the plugin and dependent artifacts: this does not cover non-Java artifacts. The problem with using non-Java artifacts within the runtime build environment is that it is not a matter of creating a classpath and referencing the artifacts from the local Maven repository; but rather, the artifacts may need to reside in specific locations on the build machine. For example, I have artifacts that NMaven resolves and installs into the GAC to support the Maven plugins written in .NET. Similar problems exist within C (or Java with JNI) environments with the need to resolve and add artifacts to the LD_LIBRARY path. In short, to support non-Java builds with Maven, we must be able to resolve and install artifacts into multiple locations and/or repositories.

More specifically, when a developer wants to support a new language within Maven, they face the need to mix both Java and the target language within the plugins/components. For example, NMaven supports writing Maven plugins in C#, which, in turn, requires a custom AppDomainManager to load the .NET Mojos within their own application domain (similar to separate classloaders). The .NET framework requires the assembly containing the custom AppDomainManager class to be signed and installed into the GAC. I have created a net-dependencies.xml file - packaged into one of the core components - that contains information on which NMaven assemblies should be installed into the GAC. This is adequate for my purposes. This leads to an important issue, however: third-party developers have no standard way of leveraging a mix of Java and .NET assemblies to extend NMaven's build runtime. They would not be able to use NMaven's resolver since it relies on the net-dependencies.xml file and would have to build their own resolver/installer implementation. It is important to note that this is a general problem for the developer adding language support to Maven and is not a problem for the end-user developer who is building artifacts for the target language.


At a minimum, the solution should tell the Maven client where to install the artifact: LD_LIBRARY, GAC, PAB (Private Assembly Base), Maven repo, etc. The artifact provider (the one who built the artifact) should be able to specify multiple endpoints, since there are cases where the artifact may be used, say, within both the GAC and PAB. The place this information is specified in the pom could exist within a general requirements section of the pom (say installation-requirement).

Given that the installation instruction may vary considerably based on language and environment, the instructions should be general enough to account for adding new environments. One approach would be to have Maven assign Resolver(s)/Installer(s) based on the artifact endpoint type (GAC, LD_LIBRARY). For instance, if Maven sees that the artifact is a dll and that it has instructions to install into the GAC and PAB, then Maven would instantiate the GacResolverInstaller implementation and the PabResolverInstaller implementation and invoke installation method(s) on each.

A second consideration would be how to get the right ResolverInstaller implementation if it is not included within core. Take the following example. Someone comes along and wants to add Ruby support to Maven. They build a ruby gem and deploy it to a Maven repo. They put within the pom.xml file installation instructions two pieces of information: 1) artifact-endpoint-type=GEM_REPO; 2) location=$RUBY_HOME. Now they create an implementation of the ResolverInstaller that knows what to do with the location value. They package and deploy this Java artifact, calling it maven-resinstaller-gem_repo (maven-resinstaller-<artifact-endpoint-type>). Maven can now match the appropriate implementation to the artifact-endpoint-type and will be able to resolve and install the gem even though it knows nothing about gems.


  • No labels

1 Comment

  1. Actually, I see this as being more a domain of a custom artifact repository implementation. Please keep in mind that when I say that, I don't mean org.apache.maven.artifact.repository.ArtifactRepository as it currently stands. In fact, I think the current architecture is horribly suited to resolving artifacts from non-Java-friendly repositories (such as RedHat Network systems, RPM/DEB databases, .Net-specific locations, etc.). We really need to refactor maven-artifact with these alternatives in mind, and make sure that artifact resolution really implements something closer to a Strategy pattern, where custom respository implementations are responsible for any advanced logic that comes from the resolveXXX(..) methods (like metadata lookups, for instance).

    I'd really prefer to see this sort of logic captured in a custom repository implementation, with such configuration in the POM as is necessary to direct that impl to the specifics of the current system.

    Of course, a lot of this is pie-in-the-sky talk given the current state of things, but you have to start somewhere.