On 07/12/2012, at 8:36 AM, Daz DeBoer wrote:
>
>
> On 6 December 2012 13:12, Adam Murdoch <[email protected]> wrote:
>
> I suspect many projects currently apply both the 'java' and 'war' plugins, so
> this change would mean that these projects would start publishing the jar.
>
> There's also the case where configuration is injected conditionally based on
> which plugins have been applied.
>
> We could tweak this approach to make it backwards compatible (in a way): One
> goal that we have is that the 'war' plugin should not imply a particular
> implementation language, or even that there is any source at all. So, we
> would do something like:
>
> - Introduce a 'java-lang' plugin that knows how to compile java source. Same
> for Scala and Groovy.
> - Introduce a 'jvm-library' plugin that knows how to build a jvm-based
> library. Does not apply any language plugins.
> - Change the 'java' plugin to apply both these things.
> - Introduce a 'web-application' plugin that knows how to build a j2ee web
> application. Does not apply any language plugins.
> - Change the 'war' plugin to apply both the 'web-application' and 'java'
> plugins.
> - New publishing DSL publishes all components
> - Deprecate and remove the 'war' plugin
> - Deprecate and remove the 'java' plugin (or rename it to 'java-library')
>
> If the long-term plan is to deprecate both the 'war' and 'ear' plugins
> (replacing with language agnostic packaging plugins),
The 'ear' plugin is already language agnostic, so we weren't really planning on
replacing it. And we don't necessarily need to replace the 'war' plugin - we
could instead deprecate using the java language support without applying the
'java' or 'java-lang' plugin. My thought was simply that we could replace it if
this lead to a better solution for publishing, but that doesn't really seem to
be the case (we still might replace it to get rid of the implicit 'build this
war from java source').
> then the question becomes more about how to deal with the migration. Maybe
> having special rules for the 'war' plugin and 'ear' plugin would allow us to
> move forward simply, while keeping the model pure. Something like:
> - war plugin removes any jvm-library component, or maybe turns it into a
> 'secondary' publication.
It would need to remove only the jvm-library component implicitly added by the
Java plugin.
> - ear plugin removes any web-application component & jvm-library component,
> or turns it into a 'secondary' publication.
Only the implicit components.
>
> We don't currently handle publication removal, but we probably should.
> There would be no way to publish both war & jar, until we add the new
> 'web-application' plugin (and add support for multiple main artifacts).
>
> This plan lets us introduce components in a way that will work with the
> current plugins without change. The benefit is that we can grow these
> concepts internally. The downside is some extra complexity. Since the 'ear'
> and 'war' plugins are slated for removal, this complexity has an effective
> end-of-life.
>
> So I guess the options are:
> 1) Introduce the 'jvm-library' and 'web-application' plugins: new publishing
> won't work without them
> 2) Hack the current rules into the way publications are generated from the
> 'war' and 'ear' plugins: new publishing will work without new plugins
> I don't feel that strongly either way. 1) will break builds using the new
> ivy-publish plugin, but only until they apply one of the new plugins.
> Probably not too much to ask.
The downside of #2 is that the rules are not complete. What happens when I
apply the 'application' plugin? Or the 'cpp-lib' plugin? Which component wins
then? What about my custom bundling plugin? It does not solve the problem, it
just moves it into the new world.
Just to recap where we've gotten to so far, I think we have the following
options.
Note: for all these options, there will be a DSL to allow you do explicitly
declare the components to be published.
1. Publish nothing by default:
* Either the 'java' plugin or a new 'jvm-library' plugin (or both)
registers a jvm-library component.
* Need to declare exactly what to publish via the DSL.
2. Publish a single thing, inferred from the set of components declared for the
project.
* Either the 'java' plugin or a new 'jvm-library' plugin (or both)
registers a jvm-library component.
* Can replace or add to the inferred component via the DSL.
* Two variations for the rule:
* if there is exactly one component, then use it.
* if there is exactly one component, then use it. When there
are multiple components, then 2jee app wins over web app wins over jvm library
wins over jvm component.
* Fail if we can't infer the component to publish.
3. Publish everything, by default don't publish the jar:
* The 'java' plugin does not register any component.
* A new 'jvm-library' plugin registers jvm-library component.
* This implies that the 'war' and 'application' plugins will not
implicitly add a jvm-library component.
4. Publish everything, by default don't publish jar when used with war plugin
* The 'java' plugin registers a jvm-library component.
* A new 'java-lang' plugin adds java language support.
* The 'war' plugin or a new 'web-application' plugin adds java language
support but does not implicitly add a jvm-library component.
* Do the same for the 'application' plugin.
I'd like to add a new option:
5. Introduce the concept of bundling, and publish those components that do not
bundle (or imply) one of the other components:
* If I produce a jvm component and a web application that bundles that
library, then I almost always want to publish just the web application.
* If I produce a web application and a jvm component and a j2ee
application that bundles the web app and library, then I almost always want to
publish the j2ee application
* If I produce a java command-line application and a jvm component that
is bundled, then I want to publish the application.
* If I produce a jvm component and a native shared library, then I want
to publish both.
* If I produce a jvm library and a web application that does not
include that library, then I want to publish both.
Just a reminder: for all these options, there will be an underlying DSL where
you can change whatever it is that Gradle publishes by default. So, I think the
goal here is to choose an option that most often does the right thing (and
preferring an approach where you add missing stuff rather than remove unwanted
stuff). We don't need a solution that always does the right thing.
At this stage, I think option #1 or option #5 is the way to go. We can get
started without requiring any restructuring of the existing plugins (which we
still want to do at some point).
--
Adam Murdoch
Gradle Co-founder
http://www.gradle.org
VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting
http://www.gradleware.com