Gradle 4.0 Warning: What is this

Just downloaded Gradle 4.0 and gave it a try. I see this warning, which I do not understand:

Gradle now uses separate output directories for each JVM language, but this build assumes a single directory for all classes from a source set. This behaviour has been deprecated and is scheduled to be removed in Gradle 5.0.

Gradle gives me the line number in my build script. It belongs to a task that builds a special jar:

  `from sourceSets.main.allSource
  from sourceSets.main.output.classesDir`

What’s wrong with that?

1 Like

See here.

getClassesDir() has been deprecated in favour of getClassesDirs()

I assume this is to help with task caching where multiple compile steps are involved so that each can have a unique directory

1 Like

Thanks Lance for your immediately response, this was easy!

Anyway, the message separate output directories for each JVM language.. is quite misleading and in my opinion should be clarified.

I have no getClassesDir() in my build.gadle nor my settings.gradle and I am still getting this warning. Maybe a transitive dependency issue that introduced some deprecated calls?

This is my build.gradle:

/*

buildscript {
ext {
springBootVersion = ‘1.5.4.RELEASE’
swaggerVersion = ‘2.7.0’
}
repositories {
mavenCentral()
maven {
url ‘https://plugins.gradle.org/m2’
}
}
// dependencies {
// GitHub - GoogleCloudPlatform/gradle-appengine-plugin: Gradle plugin that provides tasks for uploading, running and managing Google App Engine projects
// classpath ‘com.google.appengine:gradle-appengine-plugin:1.9.42’
// (APPENGINE_HOME ENV or system property required)
// OR
// appengineSdk ‘com.google.appengine:appengine-java-sdk:1.9.42’ (with “downloadSdk” set to true)
// }
}

plugins {
id “org.springframework.boot” version “1.5.4.RELEASE”
id “me.champeau.gradle.jmh” version “0.3.1”
}

apply plugin: “java-library”
apply plugin: “idea”
//apply plugin: “appengine”

jar {
baseName = rootProject.name
version = ‘1.0.0’
}

sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8

repositories {
mavenCentral()
}

configurations {
compile.exclude module: ‘spring-boot-starter-tomcat’
compile.exclude module: ‘undertow-websockets-jsr’
}

dependencies {
runtime “org.webjars:angularjs:1.5.9”
runtime “org.webjars:webjars-locator:0.32-1”

compile "org.springframework.boot:spring-boot-starter-hateoas:${springBootVersion}"
compile "org.springframework.boot:spring-boot-starter-security:${springBootVersion}"
compile "org.springframework.boot:spring-boot-starter-undertow:${springBootVersion}"
compile "io.springfox:springfox-swagger2:${swaggerVersion}"
compile "io.springfox:springfox-swagger-ui:${swaggerVersion}"
compile "org.springframework.security.oauth:spring-security-oauth2:2.1.1.RELEASE"
compile "org.springframework.vault:spring-vault-core:1.0.2.RELEASE"
compile "org.springframework.data:spring-data-couchbase:2.2.4.RELEASE"
compile "org.springframework.data:spring-data-cassandra:1.5.4.RELEASE"
// required for: Cassandra, Vault
runtime "io.netty:netty-codec-http2:4.1.12.Final"
// to enable Datastax’ Cassandra driver running alongside Swagger 2.7.0
runtime "com.google.guava:guava:19.0"
testCompile "org.openjdk.jmh:jmh-generator-annprocess:1.19"
testCompile "org.springframework.boot:spring-boot-starter-test:${springBootVersion}"
testCompile "org.springframework.restdocs:spring-restdocs-mockmvc:1.2.1.RELEASE"

}

jmh {
fork = 0
setDuplicateClassesStrategy(DuplicatesStrategy.INCLUDE)
}

tasks.withType(JavaCompile) {
options.fork = true
options.incremental = true
}

bootRun {
// jvmArgs = [‘-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=127.0.0.1:5005’]
}

It won’t be one of your dependencies, it’ll be one of your plugins. As gradle 4 is hot off the press it might take a while for plugin authors to fix & release a new version

In my case my project is capable to be built by Gradle 2.14.1, 3.5 and 4.0 and due to corporate restrictions I can’t easily push Gradle 4.0.

That warning is annoying and can be disables with using DefaultSourceSetOutput.setClassesDir(...) call.

See details in my answer: https://stackoverflow.com/a/44894025/173149

You could write a backwards compatible util

import java.lang.reflect.Method;
import org.gradle.api.tasks.SourceSetOutput;
public class SourceSetOutputHelper {
    private static Method getClassesDirs = maybeGetMethod(SourceSetOutput.class, "getClassesDirs", null);
    
    private static Method maybeGetMethod(Class<?> type, String name, Class[] argTypes) {
       try {
          return type.getMethod(name, argTypes);
       } catch (NoSuchMethodException e) {
          return null;
       }
    }

    public static Set<File> getClassesDirs(SourceSetOutput sso) {
        if (getClassesDirs == null) {
           return Collections.singletonSet(sso.getClassesDir());
        }
        try {
            FileCollection dirs = (FileCollection) getClassesDirs.invoke(sso, null);
            return dirs.getFiles();
        } catch (Exception e) {
            throw new RuntimeException(e);
        } 
    }
}

We started getting this too, and we did find a usage of classesDir, but the warning didn’t go away after removing it. :confused: