Well maybe a more expressive example is needed. Just for the record in Java EE the archive layout is like this:
Ear
\--- lib
| |- tool-jar-1
| |- tool-jar-2
|- ejb-module (0..n)
|- war-module (0..n)
|-WEB-INF
\--- lib
|- tool-jar-3
Lets say I have a gradle build for a war
:
build.gradle
plugins {
id 'war'
id 'maven-publish'
}
dependencies {
// we do not declare these as implementation as they should not be packed inside the war
providedCompile 'commons-logging:commons-logging:1.0'
// still there are dependencies that noone else will or should use so we package them within the WEB-INF/lib
implementation 'infrastructure:core:1.0'
}
publishing {
publications {
mavenJava(MavenPublication) {
from components.web
}
}
}
Lets assume this war
contains some useful functions (responding to infrastructure pings or general REST services) that must be included in every ear
that is installed on a customer application server (in our case we never ever deploy war
s self contained, they must always be part of a ear
) and we deliver about 10+ different ear
s.
The ear
s are part of completely different projects (independend git-repositories, builds, developer, release-cycle).
These projects consume the war
and package most of the war
s dependencies (the provided
ones) inside their ear
s lib directory.
plugins {
id 'ear'
}
dependencies {
// this works as usual
deploy project(path: ':local-war', configuration: 'archives' )
earlib project(path: ':local-war', configuration: 'providedCompile' )
// this worked with 'maven' and is broken with 'maven-publish'
deploy group: 'com.mycompany', name: 'common-war', version: '1.0'
earlib group: 'com.mycompany', name: 'common-war', version: '1.0', configuration: 'provided'
...
}
This way a conflict resolution can occur if the local-war
wants to use commons-logging:commons-logging:1.1
while the other expects 1.0
. Even more important a conflict will occur when 2.0
is requested (in the application server normally the library in the ears lib wins, no matter what you package, so this information is very important!).
While this may not be a big thing in the minimal example, our ear
s have numerous war
s included with many overlapping dependencies (I don’t exaggerate when the size of a ear
without stripped war
s would be 3-5 times bigger than it is now).
The war-labeled-jar can not work. The structure is totaly different (classes need to go in WEB-INF/classes, the web resouces to the root), IDE support will be completely broken and we will miss out libs that must be packaged.
Even if one does not like the use of the providedCompile
configuration (or provided
scope) for stripped war
s there is still that big thing with dependency version conflicts.
A ear containing a incompatible version of a wars dependency in its lib
directory will break the wars implementation and without dependency information no buildsystem has even remotely a chance to detect that.