Gradle Buildship insists on changing JRE library to 1.7. Why?

I am trying to debug a problem wherein a colleague keeps getting the dreaded error

  Unsupported 
  major.minor version 52.0

when trying to load project in Eclipse. I’m trying to understand this and none of it makes sense. There is a project that was built with 1.7 JRE library. I fixed that, getting rid of all mentions of “1.7” in all the settings files. But whenever I refresh the project or reimport the project , it goes back to 1.7. The default workspace JRE is jdk-1.8. what is going on here?

Buildship will use what the project specifies. If it specifies nothing, then the Java version that Gradle is running with will be used. I suggest properly setting the sourceCompatibility of the project to the value you want.

Not so, it appears. I explicitly set everything (the facet, the JRE library on the build path, the compiler compliance level, to 1.8. I run Refresh Gradle Project and everything is back to 1.7.

Please explain what you mean by “what the project specifies”. I search the project before running "Refresh Gradle Project and no instances of 1.7 anywhere. Afterward, everything is set back to 1.7

Please explain what you mean by “the Java version that Gradle is running with will be used”. This is the JRE version with which Eclipse starts? Looking at Eclipse.ini, I see -Dosgi.requiredJavaVersion=1.7 but I have no idea who put that there or what it means. I tried changing that to 1.8 and it didn’t help. I don’t see a setting for gradle java version under the gradle properties.

I could set source compatibility to 1.8 on every gradle project I have but I don’t think I should have to do this.

Can you please create a reproducible example on GitHub?

How in Eclipse can you find what version of Java gradle is running with? in buildship, attempting a run with a --version argument is rejected, although you can use that switch on the command line.

I tried but I can’t make a reproducible example. I can tell you that the particular project where this happens uses the gradle-ospackage-plugin which depends on the redline-rpm pakcage. I tried making a project with these dependencies and the problem doesn’t occur.

Can you tell me if there is anything in the code of buildship that can ever cause a requested jvm load to “downshift” to an earlier version if something isn’t right? Because that sure looks like what is happening here.

This should not be important, because you should always specify sourceCompatibility for your Java projects. Buildship will use that.

Then I’m afraid I can’t help you out. The sourceCompatibility is well tested, so without a reproducible example I’ll have to assume that the build you are talking about is not configured correctly.

There is no such thing.

I added the following to my build.gradle:

project.tasks.withType(JavaCompile){
    configure {
        sourceCompatibility=1.8
    }
}

I then tried Refresh Gradle Project, and once again it converted the project to 1.7. Everything in the project was set to 1.8 explicitly, there were no instances of the string “1.7” in any of the files, yet buildship converted it to 1.7.

OK, I have a reproducible example.
See https://github.com/sc1478/gradle/blob/master/rpm_gradle.zip

This file, rpm_gradle.zip is an export from an eclipse project. It is a project we use except that everything has been stripped out of it. There is no code. The build.gradle is pretty much intact except it doesn’t point to my corporate Maven repo, but to JCenter and the dependency on gradle.ospackage has been reset to a publicly available version. Nonetheless, it still exhibits the same problem: As it is now both the Java build path (.classpath) and the compiler level are set to jdk-1.8. Simply running Gradle ->Refresh Gradle Project changes everything to 1.7.

Another interesting factoid here: When I build the non-stripped out version of this project I see this in my console:

:compileGroovywarning: [options] bootstrap class path not set in conjunction with -source 1.7
1 warning

When my colleague tries to use the version of this plugin that my build put in our local maven repo, he sees

Caused by: java.lang.UnsupportedClassVersionError: com/netflix/gradle/plugins/rpm/Rpm : Unsupported major.minor version 52.0

I can’t think of an explanation of any of this.

You need to configure the sourceCompatibility on the project, not on the Java compile tasks. The compile tasks as well as the Eclipse model automatically pick up the project setting.

The error you posted is also a direct consequence of that. You only configured the JavaCompile tasks, so GroovyCompile was not configured. That’s why you should use the project level setting as shown in the user guide.

Thanks, but no, I think there’s a bug here. Your suggested workaround doesn’t help.

I moved the sourceCompatibility=1.8 to the project level with the same results.

It is not the answer in this case. Something in the dependencies or organization of the project is making this happen. It happens with no other projects I work with, and in none of those do I need to set sourceCompatibility.

Please do the same with the sample I sent you yesterday. You will see it for yourself. As soon as buildship refreshes the project it changes everything to 1.7. In an earlier post, I referred to this as “downshifting”. You said there’s no such thing. But I have seen it over and over and I’d like to know why.

You asked me to create a example, and I did. Please look at my example and respond to it.

https://raw.githubusercontent.com/nebula-plugins/nebula-core/b676bbc026d0053494b5439ba8ef147c16adabba/common.gradle

Sets source and target compatibility to 1.7.

After setting both of them to 1.8 after applying the above plugin, everything works as expected.

Normally you only need to set sourceCompatibility. targetCompatibility is the same by default. But since that plugin sets both, you also need to overwrite both to your desired value.

That being said, It’s probably a bad idea to apply the defaults of another company to your projects. Among other things, it also sets the group id to com.netflix.nebula. It’s not meant to be used by others than the Netflix team.

1 Like

Whooomp! There it is!

I started looking at the dependencies.

This line is the killer, I think.

apply from: 'https://raw.githubusercontent.com/nebula-plugins/nebula-core/b676bbc026d0053494b5439ba8ef147c16adabba/common.gradle'

That URL contains:

sourceCompatibility = 1.7
targetCompatibility = 1.7

Why do I apply this URL? As best I can remember, it is because this project is an extension of the gradle-ospackage-plugin and for some reason, this helped me get around a problem. Exactly what that was I no longer remember. That apply statement was in the gradle-ospackage-plugin itself, which is where I got such an odd construct. It’s clearly a hack.

Guess I need to fix that. I can’t see where anything in there helps me. It was just some crazy idea I had months ago, when I was a flailing about newbie, that seemed to help something but didn’t seem to hurt anything and so I forgot about it. Now it hurts… Can’t even imagine why nebula folks felt compelled in include such a hack.

It’s not a hack for the Netflix guys, it’s their defaults that every Nebula project uses. Makes perfect sense for them, but is not meant to be reused by anyone else.

Live and learn. You are learning a system, and have some crazy-ass idea, you drop it in your code, it doesn’t seem to do any harm, and yet it’s just wrong. It can possibly persist for months, years, whatever. Removing that silly apply caused absolutely no problems and everything that built with it builds without it.

As a matter of fact it didn’t do any real harm. It had nothing to do with the problem my colleague was having. His problem was caused by trying to run jdk-1.8 stuff in an Eclipse installation that was running on jdk-1.7. Eclipse itself, not the loaded JREs. But this looked suspicious and I wanted to get to the bottom of it.

Thanks for your help.

So what is the rule? If a build script contains two different sourceCompatibility versions, as mine essentially did, does Gradle pick the lowest one, or the first one it encounters?

  • sourceCompatiblity = JVM that you’re running on by default
  • targetCompatiblity = sourceCompatibility by default
  • if they are set explicitly, then whoever sets them last wins

The problem was that you weren’t overwriting targetCompatibility, which had been explicitly set to 1.7.