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

Reply via email to