Context

In a typical Maven case, the classifier may be used to classify an artifact as JDK-1.3 or JDK-1.4 for its target platform. In the case of J2ME, things get more complicated and such a single classifier becomes problematic because there can be many classifiers (which are referred to as requirements needed for the artifact to be used on the target platform). For example, the artifact may require libraries for MMS support or certain media support (JSR-135) to be able to build. To this day, Maven still has not adequately addressed this part of the Java world. We also have a similar case in the .NET world, where we are targeting different processors, framework versions, vendor implementations and so on. The general problem is taking Maven from supporting the J2SE world, which has great cross-platform support, to environments that are partially cross-platform.

Solution

The way NMaven currently handles this problem, is to use the public key token ID, from a signed .NET artifact, as the classifier. Then I can attach requirements (or attributes) to that classifier. For example, say that the value of my public key token ID is 4b435f4d76e2f0e6. I can associate with that value the following attributes: vendor=microsoft, frameworkVersion= 2.0. This has the implication that only signed artifacts can have artifact requirements. To understand this approach, requires understanding the constraints of the system. First there is only one classifier within the pom (and its associated dependency object within the Maven API). Second, the Global Assembly Cache - where Microsoft strong-named assemblies are stored for a global context - uses the public key token ID within the path of the assembly. Thus if I have a classifier (pom), some associated meta-data (RDF) tied to that classifier, and the classifier value (4b435f4d76e2f0e6) within the path of the assembly within the GAC, then I can always tell what the requirements are for an artifact, regardless of whether they are stored in the local repository or an external repository such as the GAC. If I need new requirements, I just sign the assembly with a different key, still having both artifacts in the GAC.

This .NET solution would not apply to Java's case, but I think that it is important to understand at least one context of the problem and how it is solved. Other contexts could also be drawn from the J2ME world. What I am convinced of - in the general case - is that using a GUID for the classifier and then having associated attributes tied to that GUID makes a lot of sense. If we take the case of multiple classifiers, then we would need more sophisticated matching process to tell whether two artifacts are indeed different. A GUID, as the classifier, allows two artifacts - with the same groupId, artifactId, version - to differentiate themselves by matching a single field. Then it is just a matter of associating the requirements to that classifier value/GUID.

The solution should be general enough to handle artifact requirements from any platform, including .NET, as well as J2ME foundations and profiles. The solution should also allow the artifact provider to add multiple requirements (probably through name-value pairs) to the artifact. This implies that we would need a pluggable matching framework that would allow the provider/framework developer to specify that requirements with certain names would use configured classes for handling of that match. For instance, if I specify name-value requirements as Software.NET.FrameworkVersion=1.1+ within the pom, then I should be able to configure the framework to invoke matcher class NetFrameworkVersionMatcher that knows how to determine the match. If we use a GUID for the classifier, this pluggable matching framework is not directly required for the expanded classifier support but is a necessary part to make it a fully working solution.