compileOnly dependencies are not available in tests

I have the following simple build.gradle file:

`
apply plugin: ‘java’

repositories {
jcenter()
}

dependencies {
compileOnly 'javax.servlet:javax.servlet-api:3.1.0’
testCompile ‘junit:junit:4.12’
}
`

And I have a simple JUnit test which tests a Servlet. However my project does not compile, because javax.servlet:javax.servlet-api:3.1.0 dependency is not available to compileTestJava task.

RFM, that’s what the manual says. See chapter 45.5, or the release notes.

How to set ‘javax.servlet:javax.servlet-api:3.1.0’ in compileOnly and testCompileOnly ?

You just simply have to list it twice.

dependencies {
    compileOnly 'javax.servlet:javax.servlet-api:3.1.0'
    testCompileOnly 'javax.servlet:javax.servlet-api:3.1.0'
}
3 Likes

considering this was added to handle the use case of maven “provided” artifacts, it’s kinda dumb that it doesn’t actually do so vis-a-vis tests. why that approach ?

We took this approach because we wanted to treat tests as a “consumer” of your production code. In this sense it should inherit dependencies in the same way. That is, since other projects that depend on your code will not see these dependencies, neither should your tests. In many cases this does in fact result in a duplicate dependency declaration but for functional tests you’ll probably want to use a proper implementation dependency instead of the compileOnly version anyhow.

2 Likes

You could use the following configuration to avoid duplicate declarations.

sourceSets {
    test.compileClasspath += configurations.compileOnly
    test.runtimeClasspath += configurations.compileOnly
}
8 Likes

For me the above was not working, but the following statement is:

// give test dependencies access to compileOnly dependencies to emulate providedCompile
configurations {
    testImplementation.extendsFrom compileOnly
}
5 Likes