Application plugin generates wrong classpath for bare .class files

plugins

(Alex Fraser) #1

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.


(Lance Java) #2

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


(Alex Fraser) #3

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!


(Alex Fraser) #4

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.


(Lance Java) #5

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'


(Alex Fraser) #6

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.


(Lance Java) #7

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

assemble.dependsOn filterJar

(Alex Fraser) #8

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?