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