Hi,

Another question we need to sort out is how we map different component 
packagings to Ivy and Maven repositories.

Packaging refers to the way a component is assembled into artefacts. Here are 
some examples:

A Java library might be packaged as:
* A jar
* API jar + implementation jar.
* A fat jar.
* An OSGi bundle.
* A distribution zip.
* A native shared library.
* A native installer or package (e.g. .rpm or .deb).

A Java command-line application might be packaged as:
* An executable jar.
* A distribution zip with start scripts.
* A native executable (.exe, an OS X .app bundle, etc).
* A native installer or package.

A Web application might be packaged as:
* An exploded web app
* A war
* A Java command-line application that runs the web app in an embedded 
container, packaged as any of the above (wouldn't that make a nice little 
plugin?)

Cross cutting this is variant: I may have windows, linux and os x native 
executables for my command-line application. Or Groovy 1.8 and Groovy 2.0 
variants of my library.

You could think of variant as expressing 'where do you want to use this 
component?' and packaging as 'how do you want to use this component?'

We have pretty similar options here as we do for mapping variants:

Option 1. Map all packagings for a variant to a single module. So, for my Java 
library we might have:

my-org/my-lib/1.2
    pom.xml with packaging = api-impl-jar
    my-lib-1.2-impl.jar
    my-lib-1.2-api.jar
    my-lib-1.2-source.zip
    my-lib-1.2.zip (or maybe my-lib-1.2-dist.zip)

Option 2. Map each packaging to a separate module. So, for my Java library we 
might have:

my-org/my-lib-jar/1.2
    pom.xml with packaging = api-impl-jar
    my-lib-1.2-impl.jar
    my-lib-1.2-api.jar
    my-lib-1.2-source.zip

my-org/my-lib-dist/1.2
    pom.xml with packaging = java-library-dist
    my-lib-1.2.zip

Option 1 has the problem that in general each packaging has its own meta-data. 
For example, if I use the default jar packaging, then at compile time you need 
my-lib-1.2.jar, whereas if I use api+impl packaging, then at compile time you 
need my-lib-1.2-api.jar and at runtime you need my-lib-1.2-api.jar + 
my-lib-1.2-impl.jar. Or, if I use the default jar packaging, then at runtime 
you need to provide my runtime dependencies, whereas if I use the fat jar 
packaging, then at runtime you don't need to provide anything (but you do need 
to know what's been bundled, for conflict resolution purposes).

Option 2 is just awkward. It gets worse once you mix in variants.

If you're using Ivy or Gradle descriptors, then option 1 is fine. So, we have a 
potential 3rd option:

Option 3. Map all packagings for a variant to a single module. If using Maven 
then always publish the default packaging (jar/war) in addition to any other 
packagings, plus always publish a Gradle (or Ivy) descriptor.


--
Adam Murdoch
Gradle Co-founder
http://www.gradle.org
VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting
http://www.gradleware.com

Reply via email to