How to exclude dependent jars from WEB-INF/lib for OSGi web bundle


(blackbeltdev) #1

I need to exclude all transitive compile dependencies from going into my WEB-INF/lib since these will available in the OSGi classpath already.

I found this similar feature but it appears that this has been removed in later versions of Gradle:

http://issues.gradle.org/browse/GRADLE-725

war { libExcludeConfigurations(‘groovy’)

}

I tried setting the war.classpath property but it didn’t appear to have any affect. My goal is to only include the main sourceSet in WEB-INF/classes and leave WEB-INF/lib blank

After reading the latest DSL docs:

FileCollection classpath
  The classpath to include in the WAR archive. Any JAR or ZIP files in this classpath are included in the WEB-INF/lib directory. Any directories in this classpath are included in the WEB-INF/classes directory.

I tried

war.classpath = fileTree('sourceSets.main.output.classesDir')

but my WEB-INF/lib path is still being populated.

Any ideas?

Thanks


(blackbeltdev) #2

Actually this works :slight_smile:

war {

classpath = sourceSets.main.output.classesDir }

$ unzip -l textura.web/textura.web.app2/build/libs/textura.web.app2-1.0.0-SNAPSHOT.war
Archive:
textura.web/textura.web.app2/build/libs/textura.web.app2-1.0.0-SNAPSHOT.war
  Length
    Date
  Time
  Name
---------
---------- -----
 ----
        0
02-24-2012 14:42
 META-INF/
      737
02-24-2012 14:42
 META-INF/MANIFEST.MF
        0
02-24-2012 14:42
 WEB-INF/
        0
02-24-2012 14:42
 WEB-INF/classes/
        0
02-24-2012 14:42
 WEB-INF/classes/com/
        0
02-24-2012 14:42
 WEB-INF/classes/com/textura/
        0
02-24-2012 14:42
 WEB-INF/classes/com/textura/web/
        0
02-24-2012 14:42
 WEB-INF/classes/com/textura/web/app2/
     3268
02-24-2012 14:42
 WEB-INF/classes/com/textura/web/app2/App2Servlet$_doGet_closure1.class
     7985
02-24-2012 14:42
 WEB-INF/classes/com/textura/web/app2/App2Servlet.class
---------
                   -------
    11990
                   10 files

Original WAR:

$ unzip -l textura.web/textura.web.app2/build/libs/textura.web.app2-1.0.0-SNAPSHOT.war
Archive:
textura.web/textura.web.app2/build/libs/textura.web.app2-1.0.0-SNAPSHOT.war
  Length
    Date
  Time
  Name
---------
---------- -----
 ----
        0
02-24-2012 14:45
 META-INF/
      737
02-24-2012 14:45
 META-INF/MANIFEST.MF
        0
02-24-2012 14:45
 WEB-INF/
        0
02-24-2012 14:45
 WEB-INF/classes/
        0
02-24-2012 14:45
 WEB-INF/classes/com/
        0
02-24-2012 14:45
 WEB-INF/classes/com/textura/
        0
02-24-2012 14:45
 WEB-INF/classes/com/textura/web/
        0
02-24-2012 14:45
 WEB-INF/classes/com/textura/web/app2/
     3268
02-24-2012 14:45
 WEB-INF/classes/com/textura/web/app2/App2Servlet$_doGet_closure1.class
     7985
02-24-2012 14:45
 WEB-INF/classes/com/textura/web/app2/App2Servlet.class
        0
02-24-2012 14:45
 WEB-INF/lib/
    25962
02-15-2012 11:52
 WEB-INF/lib/slf4j-api-1.6.4.jar
     5834
02-24-2012 11:30
 WEB-INF/lib/textura.api-1.0.0-SNAPSHOT.jar
 68005993
02-15-2012 12:26
 WEB-INF/lib/glassfish-embedded-all-3.1.1.jar
  6139152
02-15-2012 11:57
 WEB-INF/lib/groovy-all-1.8.5.jar
---------
                   -------
 74188931
                   15 files

Sorry to waste your time. Hopefully this will help someone else.


(blackbeltdev) #3

As a follow up is there a way to selectively exclude some libraries? Let’s say I had some libaries that I wanted to be included in WEB-INF/lib above.


(René Groeschke) #4

Hello Kirk, the easiest way to avoid transitive dependencies in your war would be to set the transitive property of all your configurations to false:

configurations.all {
 transitive = false
}

with this snippet in your build. only the direct dependencies should show up in your war.

regards, René


(René Groeschke) #5

Another remark on getting “some libraries in your war”: The war plugin ships with the providedCompile configuration to declare dependencies, that are needed during compile time, but are provided later by the container. For more details have a look at the dependency management paragraph of the War Plugin chapter in the user guide: http://gradle.org/docs/current/userguide/war_plugin.html#N12A36

regards, René


(blackbeltdev) #6

Good tips. I was aware of the providedCompile mechanism but my problem was the transitive libraries that were being added.

There might be a case in the immediate future that I want to add a couple of transitive libraries (e.g. non-osgi libraries put in WEB-INF/lib). I suspect that i could use the classpath property again but I’m not sure how that would look.

Thanks


(René Groeschke) #7

for this case I would suggest to handle the exclusion of transitive dependencies on a more fine grained level by setting them dependency specific. You can set transitive flag to false for a specific dependency:

dependencies{
    compile ("org.acme:Proj:1.0"){
        transitive = false
    }
}

or instead of setting transitive to false exclude specific transitive deps by:

dependencies{
    compile ("org.acme:Proj:1.0"){
        exclude: group:'this', module:'that'
     }
}

again, the user guide contains a very detailed section about this stuff: http://gradle.org/docs/current/userguide/dependency_management.html

regards, René


(blackbeltdev) #8

Using that method wouldn’t that break compilation? I need the transitive dependencies for compilation I just don’t want to add them to WEB-INF/lib.

I think I would want something like (syntax is completely wrong of course)

war {

classpath = sourceSets.main.output.classesDir + project.configurations.runtime(include 'foobar.jar) }


(René Groeschke) #9

you can always postprocess the war classpath (and the content) for example by:

war{
 classpath = classpath.filter{file ->
  ...
 }
}

see http://gradle.org/docs/current/javadoc/org/gradle/api/file/FileCollection.html#filter(groovy.lang.Closure) for details


(blackbeltdev) #10

That’s the secret sauce I was looking for. Thanks!


(Rajiv Cooray) #11

Thank you guys for the pointers. I’m trying to create a WAB too and managed to get started with something like this for now:

war {

manifest = osgiManifest {

instruction ‘Private-Package’, ‘com.yyy.*’

instruction ‘Bundle-Classpath’, ‘WEB-INF/classes’

instruction ‘Import-Package’, ‘’‘groovy.*’’’

instruction ‘Created-By’, ‘yyy’

instruction ‘Bundle Description’, “${project.description}”

vendor = “yyy”

symbolicName = “${project.group}” + “-” + “${project.name}”

version = strippedVersion()

classesDir = new File( “${buildDir}/classes” )

classpath = configurations.runtime

instruction ‘Web-ContextPath’, “${name}”

}

classpath = classpath.filter { File file ->

!file.name.endsWith( (‘jar’) )

}

archiveName = “${project.group}-${project.name}-${project.version}.war” }

The problem is I have to manage the Import-Package. If I remove the manual Import-Package as above and let bnd auto generate it, the generated output isn’t correct. Bnd documentation http://www.aqute.biz/Bnd/Format#import-package mentions about the -wab directive, is there a way to invoke that? I couldn’t figure it out yet.

Thx


(Dan Winkler) #12

Is there any way to exclude certain files. For example I have foo.war dependent on foo-core.jar. Everything seems to be fine except that the persistence.xml from foo-core.jar is getting included in foo.war.


(Luke Daley) #13

Should be something like:

war {
    instruction '-wab', 'static-pages/'
}

(Eric Francis ) #14

Did you ever solve this issue?