Application plugin generates wrong classpath for bare .class files

I have two Java sub-projects, rsaquery and rsaworkers (follow links for full source). The former has an additional source set called filter that is not included in its .jar file. The output of that source set is a runtime dependency of rsaworkers:

apply plugin: 'java'
apply plugin: 'application'

dependencies {
    compile project(':rsaquery')
    runtime project(':rsaquery').sourceSets.filter.output
}

When I run gradle installDist, it copies the filter classes to the lib directory:

build/install/rsaworkers/lib/org/vpac/ndg/query/InRange.class
...

But the classpath in the startup script is wrong: it’s written as $APP_HOME/lib/filter, but it should actually be $APP_HOME/lib.

I consider the sourceSets of dependent project to be private and should never be accessed like this. Eg:

runtime project(':rsaquery').sourceSets.filter.output

A couple of options

  1. Create another jar in :rsaquery with a classifier of “filter” and depend on that instead.
  2. Create a “filter” configuration in :rsaquery and depend on it via
runtime project(path: ':rsaquery', configuration: 'filter')

More info here and here

Thanks - but I don’t quite understand how to do this. The docs are not clear.

I’ve tried creating a separate .jar file, but how can I depend on that from another project? I have asked a question about this on StackOverflow.

When you first replied I didn’t understand the configuration suggestion. I’ll have another go now. Thanks!

I tried adding a configuration to rsaquery:

sourceSets {
    filter
}
configurations {
    filter
}

And I changed rsaworker to use this dependency instead:

runtime project(path: ':rsaquery', configuration: 'filter')

But the result is the same: the .class files are copied to the lib directory, which doesn’t match the generated classpath.

Something like

sourceSets { 
   filter 
}
configurations { 
   filter 
}
task filterJar(type: Jar) {
   classifier = 'filter'
   from sourceSets.filter.output
}
artifacts {
   filter filterJar
}

And to reference:

runtime project(path: ':rsaquery', configuration: 'filter')

Or

runtime 'xxx:rsaquery:1.0:filter'

That allows a second .jar file to be built in the rsaquery project, but it does not result in the .jar file being copied to the install directory. This is what happens when I run src/rsaworker$ gradle installDist:

:rsaquery:compileJava
:rsaquery:processResources UP-TO-DATE
:rsaquery:classes
:rsaquery:compileFilterJava UP-TO-DATE
:rsaquery:processFilterResources UP-TO-DATE
:rsaquery:filterClasses UP-TO-DATE
:rsaquery:jar
[other subprojects...]
:rsaworkers:compileJava
:rsaworkers:processResources UP-TO-DATE
:rsaworkers:classes
:rsaworkers:jar
:rsaworkers:startScripts
:rsaworkers:installDist

The :rsaquery:filterJar task is not run, even though it’s available.

Ah, you’ll need to wire the task into the dag

assemble.dependsOn filterJar

That does cause filterJar to be run, but only if I run src/rsaquery$ gradle assemble. Running installDist from the rsaworker directory has the same result as before, and src/rsaworker$ gradle assemble doesn’t run on :rsaquery:assemble.

Should I just abandon this and move the filters to their own subproject?