Search code examples
javajargradle

Gradle multiple jars from single source folder


As for now we have a project structure with single source folder named src, which contains source code for three modules. What I want to do is:

1) Compile source code. This is easily done with sourceSets definition:

sourceSets {
    main {
        java {
            srcDir 'src'
        }
    }
}

2) Put compilation results into three jars. I am doing this via three 'jar' type tasks:

I am doing this now via three separate tasks:

  • util.jar

    task utilJar(type: Jar) {
        from(sourceSets.main.output) {
            include "my/util/package/**"
        }
    }
    
  • client.jar

    task clientJar(type: Jar) {
        from(sourceSets.main.output) {
            include "my/client/package/**"
        }
    }
    
  • server.jar

    task serverJar(type: Jar) {
        from(sourceSets.main.output) {
            include "**"
        }
        excludes.addAll(utilJar.includes)
        excludes.addAll(clientJar.includes)
    }
    

The thing is that server.jar should contain all classes that are not contained within client.jar and util.jar. In ant build script we solve this problem by using difference ant task. How this can be done in gradle (my current approach doesn't work)?

Maybe my approach is completely wrong. Please advice.

P.S. as for now we CAN NOT change the project source code folder structure.


Solution

  • I will post my working solution here as an answer (I've got a hint on gradle's forum).

    The scopes in gradle are very strange thing :) I thought that every task definition creates an object of some 'Task' class, which is something like 'JarTask' in this particular case. Then I can access any property of the class from anywhere in my build.gradle script. However, I found the only place where I can see the patterns, which are included in jar file - inside a from block of a task. So my working solution for now is to:

    1) Define a project-level collection to contain patterns to be excluded from server.jar

    2) Exclude all patterns in from block of serverJar task.

    Please see final version below

    sourceSets {  
        main {  
            java {  
                srcDir 'src'  
            }  
        }  
    } 
    
    // holds classes included into client.jar and util.jar, so they are to be excluded from server.jar
    ext.serverExcludes = []
    
    // util.jar
    task utilJar(type: Jar) {  
        from(sourceSets.main.output) {  
            include "my/util/package/**" 
            project.ext.serverExcludes.addAll(includes)
        }  
    }
    
    // client.jar
    task clientJar(type: Jar) {  
        from(sourceSets.main.output) {  
            include "my/client/package/**"
            project.ext.serverExcludes.addAll(includes)
        }  
    }
    
    // server.jar
    task serverJar(type: Jar) {  
        from(sourceSets.main.output) {  
            exclude project.ext.serverExcludes
        }  
    }