Gradle sourceCompatibility has no effect to subprojects

JavaGradleCompatibilityBytecode

Java Problem Overview


I have Java 6 and 7 installed on my machine. Gradle uses 1.7 (checked using gradle -v). But I need to compile my code to be compatible with Java 1.6. As far as I understand the documentation I can use the sourceCompatibility property to do so (and indirectly the targetCompatibility which defaults to the sourceCompatibility).

So I added the following line to my build file (on the root level, not in any closure):

sourceCompatibility = 1.6

(to be sure I also added the targetCompatibility = 1.6 in some trials, but that should not make a difference)

To check whether the result was actually compatible with 1.6 I unzipped the resulting jar, cd into the WEB-INF/classes folder and used javap -verbose on the first .class file I encountered. But no matter whether I set the target compatibility or whether I used 1.5 instead of 1.6 or whether I specified it as string ('1.6'), each time the result of javap was

minor version: 0
major version: 51

Afaik this means it is Java 1.7 Bytecode, which is wrong.

Any ideas why the sourceCompatibility-setting doesn't work? Or is javap not the correct way to check the compatibility?

UPDATE: Yes, this is actually a multi-project build but I only checked one of the subprojects' build results. In this subproject's build file I made the mentioned changes to be sure they are actually applied. In addition, I added the following in the root project's build file (as @Vidya proposed as well):

allprojects {
    sourceCompatibility = 1.6
    targetCompatibility = 1.6
}

But this didn't help either.

UPDATE 2: I checked the setting of sourceCompatibility with this snippet in the relevant build.gradle files:

compileJava.doFirst {
    println "source compatibility " + sourceCompatibility
}

It revealed that my sourceCompatibility is set to 1.7 although I tried to set it to 1.6. When I extracted the simplest subproject and built in on its own the sourceCompatibility is set correctly and the Java Byte code is compatible to 1.6. However, even this sub-project uses the wrong sourceCompatibility when used in the multi project build.

BTW: The plugins I use in some of the sub projects are: java, war, jetty, gwt

UPDATE 3: I changed the built scripts to just use the java plugin (and thus just construct some jars) and removed the usage of the war, jetty and gwt plugin. But still all the projects are set to sourceCompatibility 1.7 despite me setting it in the allprojects section and in some of the sub projects. All that is left now in the build scripts is the declaration of some decencies (maven, files and other sub projects), the declaration of the repositories to use, the declaration of some others tasks (that the build-task does not depend on, so it shouldn't be affected) and the configuration of the manifest file for the created jar files (I add a specification and an implementation version and title to the manifest file).

I don't see how any of that would affect the sourceCompatibility setting.

Java Solutions


Solution 1 - Java

It seems this behavior is caused by specifying the sourceCompatibility before apply plugin: 'java', which happens if you try to set the compatibility option inside allprojects.

In my setup, the situation can be solved by replacing:

allprojects {
    sourceCompatibility = 1.6
    targetCompatibility = 1.6
}

with:

allprojects {
    apply plugin: 'java'
    sourceCompatibility = 1.6
    targetCompatibility = 1.6
}

Will be glad if anyone else can verify this in a different setup.

I am still not sure whether this should be reported as a bug but I believe this solution is better than the work-around mentioned above (which has been very helpful however).

Solution 2 - Java

Symptoms indicate that somewhere somebody is overwriting project.sourceCompatibility. But given that there are many ways to customize Gradle, I can't say from a distance who that is.

As a workaround, you can set the properties on the task level, which is what ultimately counts:

tasks.withType(JavaCompile) { 
    sourceCompatibility = "1.6"
    targetCompatibility = "1.6" 
}

Add this to allProjects { ... } block.

Solution 3 - Java

You need to define compileJava tasks in build.gradle file, if you are using sourceCompatibility or targetCompatibility. Without compileJava tasks, both compatibility variables are displayed as unused variables in Intellij. I am using Gradle version 2.10.

Solution 4 - Java

To solve this problem, just check the build Gradle (app), and put the below code inside it.

compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
}

Also in the build Gradle (project), you have to have the below code.

allprojects {
    repositories {
        google()
        mavenCentral()
        jcenter()
        sourceCompatibility = 1.6
        targetCompatibility = 1.6
    }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJoachim KurzView Question on Stackoverflow
Solution 1 - JavaMarwinView Answer on Stackoverflow
Solution 2 - JavaPeter NiederwieserView Answer on Stackoverflow
Solution 3 - JavaRajkumar NagarajanView Answer on Stackoverflow
Solution 4 - Javahassan bazaiView Answer on Stackoverflow