1

Gradle has source Compatability and the targetCompatability variables that can be set. Eclipse has JDK compliance, generated class files comapatability, and source compatibility.

Is there any way to automagically set one from the other? Ideally, the Gradle stuff would be set from the Eclipse stuff.

edit: these things appear to be stored in: org.eclipse.jdt.core.prefs

edit2: they look like:

D:\ray\dev\conradapps\printg>cat .settings\org.eclipse.jdt.core.prefs eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve org.eclipse.jdt.core.compiler.compliance=11 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.release=disabled org.eclipse.jdt.core.compiler.source=1.8

i can make it work as follows, but it's a hack :)

import java.io.IOException;
import java.nio.file.*;
import java.util.*;
plugins {
    id 'java-library'
    id 'application'
    id 'distribution'
}

repositories {
    jcenter()
}
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
dependencies {
    testImplementation 'junit:junit:4.12'
}
String myMainClass='p.Main'
jar {
  manifest {
    attributes(
      'Main-Class': myMainClass
    )
  }
}
application {
    mainClassName = myMainClass
}
class Hack {
    static String[] hack() throws IOException {
        System.out.println("Working Directory = "+System.getProperty("user.dir"));
        String dir="./.settings";
        String name="org.eclipse.jdt.core.prefs";
        File file=new File(dir,name);
        String[] strings=new String[3];
        for(int i=0;i<strings.length;i++)
            strings[i]="";
        if(file.exists()) System.out.println(file.toString()+" exists.");
        else return strings;
        List<String> lines=new ArrayList<>();
        try {
            if(usePath) {
                Path path=FileSystems.getDefault().getPath(dir,name);
                lines=java.nio.file.Files.readAllLines(path);
            } else {
                BufferedReader bufferedReader=new BufferedReader(new FileReader(file));
                for(String line=bufferedReader.readLine();line!=null;line=bufferedReader.readLine())
                    lines.add(line);
                bufferedReader.close();
            }
            int index;
            for(String line:lines) {
                if(line.startsWith("org.eclipse.jdt.core.compiler.compliance")) {
                    index=line.indexOf("=");
                    if(index>0) {
                        System.out.println("compliance: "+line.substring(index+1));
                        strings[0]=line.substring(index+1);
                    }
                }
                if(line.startsWith("org.eclipse.jdt.core.compiler.source=1.8")) {
                    index=line.indexOf("=");
                    if(index>0) {
                        System.out.println("source: "+line.substring(index+1));
                        strings[1]=line.substring(index+1);
                    }
                }
                if(line.startsWith("org.eclipse.jdt.core.compiler.codegen.targetPlatform")) {
                    index=line.indexOf("=");
                    if(index>0) {
                        System.out.println("target: "+line.substring(index+1));
                        strings[2]=line.substring(index+1);
                    }
                }
            }
        } catch(Exception e) {
            System.out.println("caught: "+e);
        }
        return strings;
    }
    public static void main(String[] args) throws IOException {
        hack();
    }
    static boolean usePath;
}
println("java version is: ${JavaVersion.current()}")
String[] strings=Hack.hack();
if(strings[1]!="") {
    println 'setting source'
    sourceCompatibility = strings[1]
}
if(strings[2]!="") {
    println 'setting target'
    targetCompatibility = strings[2]
}
Ray Tayek
  • 9,841
  • 8
  • 50
  • 90

1 Answers1

0

Yes. If you want Gradle to give your configuration to Eclipse, basically, as of Gradle 5.1.1, just add:

sourceCompatibility = '1.7'
targetCompatibility = '1.8'

to your build.gradle file. Note that until java 10 the enumeration was 1.8,1.9,1.10 but from Java 11 and future versions the enumeration is 11, 12, etc. Check the Gradle docs. If you stumble upon this answer: For me, with Gradle 5.0, the java version works with or without quotes (either 1.8 or '1.8') and this is specified in the latest version of the javadocs. It also worked both when added inside and outside of compileJava{}. I tested this on a multiproject build.

I am not sure about the Eclipse to Gradle configuration transfer. Isn't it supposed to go the other way around though? Gradle is the central configuration tool that configures the build process and whatever IDE you are using (you, or your collaborator). Even if it is possible, the Gradle does manipulate the .classpath and other Eclipse files. So to be sure, if it was a crucial point, I would prefer to add the configuration to the Gradle and let that deal with Eclipse or any other IDE's files.

tryman
  • 3,233
  • 1
  • 12
  • 23
  • i was looking for a way to have the build script get the values from eclipse somehow – Ray Tayek Jan 18 '19 at 05:58
  • This initiates a cycle though. It is my understanding, that Eclipse does not really ask Gradle how to do anything. Instead, Gradle manipulates the files Eclipse loads: .classpath, org.eclipse.jdt.core.prefs, etc. So if in org.eclipse.jdt.core.prefs you see "org.eclipse.jdt.core.compiler.compliance=11", then the compliance is that of Java 11. To test that, you can disable any specific compliance settings from inside Eclipse and then check the file org.eclipse.jdt.core.prefs: with and without the configuration commands in build.gradle. – tryman Jan 18 '19 at 19:13
  • @RayTayek Did you try it? Any news on this? – tryman Jan 24 '19 at 10:03
  • no, i want the gradle source and target to be like eclipse automagically while i am in development. – Ray Tayek Jan 25 '19 at 16:44
  • That's what I was trying to say above but obviously I didn't express it well. So: Eclipse will !always! load its configuration regarding the source/target platform from org.eclipse.buildship.core. If there is no source/target platform specified there it will fall back to the workspace source/target platform settings (typically, if you haven't changed them, these will be inferred from the installed jdk). If there is a source/target platform configuration inside the file, then this will override the workspace settings and will use those project-specific settings found there. – tryman Jan 25 '19 at 18:43
  • Now, what does Gradle? Gradle does nothing, unless you explicitly tell it to do something in its build.gradle file. If you don't specify a source/target platform (eg.`targetCompatibility = 10`) then it won't write anything there and Eclipse will load the file normally. – tryman Jan 25 '19 at 18:47
  • If you tell it to do something, like `targetCompatibility = 10`, only then will it write this to the org.eclipse.jdt.core.prefs file. Subsequently, when Eclipse loads that file, it will use the Gradle's configuration. (Sorry but when in the first comment I wrote "org.eclipse.buildship.core.prefs", I meant the "org.eclipse.jdt.core.prefs" file. – tryman Jan 25 '19 at 18:50
  • That's what I meant by "this initiates a cycle though". Eclipse will use its own settings, unless you tell Gradle to mess with Eclipse's org.eclipse.jdt.core.prefs. The way you tried to do it, was to specify something through Eclipse which would write it in the org.eclipse.jdt.core.prefs file. Then, to make sure it was not ovewritten by Gradle, you read that file first and made Gradle rewrite that same thing. While inventive, you could just not specify anything at Gradle and would leave that file untouched, as Eclipse originally configured it. – tryman Jan 25 '19 at 19:00
  • [By the way, I use Gradle 5.0, not sure if some older version was bad-behaved and did write in the file]. If this is what you looked for, I will update my answer above to incorporate that. – tryman Jan 25 '19 at 19:00
  • i don't understand what you are saying. my solution does what i want. – Ray Tayek Jan 25 '19 at 19:23
  • What I am saying is, have you tried to just not write the `sourceCompatibility` and `targetCompatibility` in your build.gradle file? If you don't specify anything, it will use Eclipse's configuration. You did't need to do anything at all and Gradle would use Eclipse's settings – tryman Jan 25 '19 at 19:39
  • i get: D:\ray\dev\conradapps\printg>gradlew clean > Configure project : java version is: 11 Working Directory = D:\ray\dev\conradapps\printg .\.settings\org.eclipse.jdt.core.prefs exists. from eclipse, target: 1.8 from eclipse, compliance: 11 from build file, target 11 set target to 1.8 BUILD SUCCESSFUL in 5s 1 actionable task: 1 up-to-date – Ray Tayek Jan 25 '19 at 20:28
  • i haven't actually looked at the class files to see the version, so it could be wrong. – Ray Tayek Jan 25 '19 at 20:30
  • Ok, now I got confused. From build file, you mean from the "build.gradle"? – tryman Jan 25 '19 at 21:02
  • yes, from the goovy variables: sourceCompatibility and targetCompatibility – Ray Tayek Jan 25 '19 at 21:08
  • Ok.What I am saying is you should _remove_ those variables from your build.gradle file. Then, gradle will _not modify_ the "org.eclipse.jdt.core.prefs" file and your Eclipse's settings for sourceCompatibility and targetCompatibility will be used. – tryman Jan 25 '19 at 21:18
  • they were removed and the output above. – Ray Tayek Jan 26 '19 at 11:05