On 16/09/2011, at 9:26 PM, Luke Daley wrote:
>
> On 15/09/2011, at 10:07 PM, Adam Murdoch wrote:
>
>> So, if we work around the problem for the war plugin, we still have exactly
>> the same problem in the ear plugin, and the c++ plugin, and when you publish
>> a source jar and javadoc jars (and the signing plugin, to some extent).
>>
>> There are some simple solutions to this problem, I think:
>>
>> Option 1: artifact type filtering
>> * Change configurations so that they support filtering on an artifact's type
>> when resolving.
>> * Change the various compile and runtime configurations to accept artifacts
>> of type 'jar'.
>> * Change the war and ear plugins so that they do not disable and remove the
>> jar.
>> * Probably change the signing plugin so that it add the signatures to '*'
>> (ie signatures are cross-cutting).
>>
>> Option 2: bust up archives configuration
>> * Add 'jars', 'sources', 'javadocs', 'wars', 'ears', etc configurations.
>> * Change the 'runtime' configuration to extend from 'jars' instead of
>> 'archives'.
>> * Add a 'publications' configuration which extends 'jars', 'sources',
>> 'javadocs', 'wars', 'ears', 'signatures', etc.
>> * Change the java plugin to add the jar to the 'jars' configuration.
>> * Change the war plugin to add the war to the 'wars' configuration.
>> * Change the ear plugin to add the ear to the 'ears' configuration.
>> * Change the war and ear plugins so that they do not disable and remove the
>> jar.
>>
>> User runs 'gradle uploadPublications' instead of 'gradle uploadArchives'. We
>> might keep the 'archives' configuration, have it extend from 'publications',
>> and deprecate 'archives' and 'uploadArchives'.
>>
>> Option 3: artifacts in multiple configurations
>> * Change the ArtifactHandler so that it adds artifacts of type 'jar' to both
>> the 'archives' and 'runtime' configurations.
>> * Change the 'default' configuration so that it no longer extends from
>> 'archives'.
>> * Change the war and ear plugins so that they do not disable and remove the
>> jar.
>>
>> We could potentially combine both options 2 and 3. For me, option 3 is the
>> way to go, followed at some point by option 2. Later, we will need option 1,
>> for more sophisticated resolution (eg for fixing how we treat transitive
>> dependencies, and for dealing with native variants).
>
> I think the ideal solution is 2 with some extra work.
>
> * Rework the java plugin so it does not create a jar, but adds the tools for
> java projects in general
> * Add a “jars” plugin that provides a dsl for configuring jars to be built
> (applies “java” plugin)
> * Add a “jar” plugin that applies “jars” and preconfigures to create one jar.
> * Follow this same pattern for the current war and ear plugins (e.g. “wars”
> plugin adds the capability, “war” plugin preconfigures a single war).
>
> * Add a model element for each kind of thing in a container (e.g. jars.main,
> wars.main)
> * Add a top level element that is a synonym for jars.main (e.g. jar {} ==
> jars.main {})
> * Expose the configurations used by each thing through that element (e.g.
> jars.main.dependencies.runtime instanceof Configuration)
> * Allow assignment of configurations (e.g. jars.main.dependencies.runtime =
> configurations.someConfiguration)
> * Expose the publication for wiring into other configurations via some
> interface that Configuration knows about that is implemented by the model
> objects (i.e. jar, war, ear)
>
> war {
> dependencies {
> compile jars.main
> }
> }
>
> I think that should still give us the flexibility to dig into the jar model
> and do things like just use the class files when compiling instead of using
> the jar I think.
This is all good stuff, and fits pretty well with where we want to go. However,
I think it can all wait until after 1.0, assuming we fix the basic problem:
when I declare a Java compile time dependency on a Gradle project (whether in
the same build or published in a repository) I get only the Jar for that
project, and not any of the other stuff the project may also produce.
Leaving it until after 1.0 means:
* A java project will always publish a jar (by default).
* We won't be able to use jar { }, war {} or ear { } namespaces as conveniences
to refer to the main archive definitions, as the archive tasks will be visible
with these names.
All the other stuff we'll be able to do later. I think this is a reasonable
trade-off, and that there's more important stuff to do before extracting a
domain model for bundling. Instead, I would let use cases drive the extraction
incrementally as we need it.
--
Adam Murdoch
Gradle Co-founder
http://www.gradle.org
VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting
http://www.gradleware.com