Bundling transitive jars in WAR

View: New views
3 Messages — Rating Filter:   Alert me  

Bundling transitive jars in WAR

by anschoewe :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello,

I'm a newbie when it comes to bundling wars.  I figured Gradle could help with this.  Oh, I'm also a newbie Gradle user.

I have a WAR project that depends on a number of other projects -the jars produced by the sub-projects.  This means that my WAR project has a compile time dependency on my sub projects.  Obviously, when I create my WAR, it will need to bundle the runtime dependencies of my sub projects in the WAR.  This is where I'm having a problem.  All of the runtime dependencies of the sub-projects live in the 'lib' folder of the each sub-project.  I noticed that Gradle only looks in the lib folder (repository) of the WAR when trying to find these run-time dependencies.  What's the best way to solve this problem?

-  Is it best practice for the WAR project to include all of the run-time dependencies of the sub-projects in its own 'lib' folder?  This doesn't feel right
- Is it possible to have Gradle look in the 'lib' folder of each sub-project for the appropriate transitive jars?  If so, is there an automatic mechanism for this?  If not, is there a generic way to refer to the repository location of my sub-projects?

I'm not using remote repositories for any of these projects.  It's all stored locally.  I tried adding 'dependsOnChildren()' in my ":Web Application" project, but it didn't help.

Thanks for any help you all might provide.  I'm really enjoying Gradle so far.

Andrew

-------------------------

Here's an example of my configuration...

Folders:

/Projects
   /Sub Project
      /lib
   /Web Application
      /lib
   settings.gradle
   build.gradle


In settings.gradle: include 'Sub Project', 'Web Application'

In build.gradle:

subprojects {
    usePlugin('java')
    version = '1.0'
    sourceCompatibility = 1.6
    targetCompatiblity = 1.6
}

project(":Sub Project") {
        repositories {
                flatDir name: 'localRepositories', dirs: ["${projectDir}/lib"]
        }
        dependencies {
                compile group: 'junit', name: 'junit', version: '3.8.2'
                runtime name: 'dbunit', version: '2.0'

        }
}

project(":Web Project") {
        usePlugin('war')
        repositories {
                flatDir name: 'localRepositories', dirs: ["${projectDir}/WEB-INF/lib"]
        }
        dependencies {
                compile project(":Sub Project")
        }
}
--------------------------
It's only looking in "${projectDir}/WEB-INF/lib" for the transitive runtime jars when bundling the WAR.  In this example, the runtime jar dbunit only lives in '/Projects/Sub Project/lib'

Re: Bundling transitive jars in WAR

by Adam Murdoch-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message



anschoewe wrote:

> Hello,
>
> I'm a newbie when it comes to bundling wars.  I figured Gradle could help
> with this.  Oh, I'm also a newbie Gradle user.
>
> I have a WAR project that depends on a number of other projects -the jars
> produced by the sub-projects.  This means that my WAR project has a compile
> time dependency on my sub projects.  Obviously, when I create my WAR, it
> will need to bundle the runtime dependencies of my sub projects in the WAR.
> This is where I'm having a problem.  All of the runtime dependencies of the
> sub-projects live in the 'lib' folder of the each sub-project.  I noticed
> that Gradle only looks in the lib folder (repository) of the WAR when trying
> to find these run-time dependencies.  What's the best way to solve this
> problem?
>
> -  Is it best practice for the WAR project to include all of the run-time
> dependencies of the sub-projects in its own 'lib' folder?  This doesn't feel
> right
>  

I agree. You shouldn't have to do this.

> - Is it possible to have Gradle look in the 'lib' folder of each sub-project
> for the appropriate transitive jars?  If so, is there an automatic mechanism
> for this?  If not, is there a generic way to refer to the repository
> location of my sub-projects?
>
>  

There's no automatic mechanism for this, though it would be nice to add
one. Could you add a JIRA issue for this?

It is, however, possible to script the behaviour you want. Here's an
example snippet of code which you could add to your root build file. For
each project, this code will add the repositories of each project it
depends on. So, for your build, it will add a 'Sub Project/lib'
repository to the 'Web Application' project.

allprojects {
    afterEvaluate { project ->
        project.configurations.each { config ->
            config.getDependencies(ProjectDependency.class).each {dep ->
                dep.dependencyProject.repositories.each {repos ->
                    if (!project.repositories.all.contains(repos)) {
                        project.repositories.add(repos)
                    }
                }
            }
        }
    }
}

An automatic solution would do pretty much the same thing, so when we
add it, you can just remove the above snippet.


> I'm not using remote repositories for any of these projects.  It's all
> stored locally.  I tried adding 'dependsOnChildren()' in my ":Web
> Application" project, but it didn't help.
>
> Thanks for any help you all might provide.  I'm really enjoying Gradle so
> far.
>
> Andrew
>
> -------------------------
>
> Here's an example of my configuration...
>
> Folders:
>
> /Projects
>    /Sub Project
>       /lib
>    /Web Application
>       /lib
>    settings.gradle
>    build.gradle
>
>
> In settings.gradle: include 'Sub Project', 'Web Application'
>
> In build.gradle:
>
> subprojects {
>     usePlugin('java')
>     version = '1.0'
>     sourceCompatibility = 1.6
>     targetCompatiblity = 1.6
> }
>
> project(":Sub Project") {
> repositories {
> flatDir name: 'localRepositories', dirs: ["${projectDir}/lib"]
> }
> dependencies {
> compile group: 'junit', name: 'junit', version: '3.8.2'
> runtime name: 'dbunit', version: '2.0'
>
> }
> }
>
> project(":Web Project") {
>         usePlugin('war')
> repositories {
> flatDir name: 'localRepositories', dirs: ["${projectDir}/WEB-INF/lib"]
> }
> dependencies {
>                 compile project(":Sub Project")
> }
> }
> --------------------------
> It's only looking in "${projectDir}/WEB-INF/lib" for the transitive runtime
> jars when bundling the WAR.  In this example, the runtime jar dbunit only
> lives in '/Projects/Sub Project/lib'
>
>  

--
Adam Murdoch
Gradle Developer
http://www.gradle.org


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email



Re: Bundling transitive jars in WAR

by anschoewe :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Your code snippet did the job.  I too would like to see this feature in future builds.  I've created an issue for it here.

The only issue with this workaround is that it requires each sub-project to have uniquely named repositories -a minor problem.  Thanks.

Andrew