Search code examples
eclipsegradleeclipse-jdtgradle-eclipse

Apply custom Eclipse formatter to Gradle project


I am currently using Eclipse Oxygen and Gradle 4.4 for a project. In Eclipse, it is possible to manually set a custom Java formatter on a workspace or a project. This requires everyone working on the team to import the formatter XML file any time they create a new workspace. To avoid teammates forgetting to apply the formatter and writing code against the agreed upon style guide, I am trying to automatically configure the Gradle projects to use our custom formatter when the projects are imported into Eclipse. The format file is in the project directory. I have not been able to find any reliable information on how best to achieve this. I have tried the following which seems to work on the surface, but seems to cause a "Faceted Project Problem (Java Version Mismatch: Java compiler level does not match the version of the installed Java project facet." error. The sourceCompatibility and targetCompatibility are set to 1.8 elsewhere in the Gradle script, but compiler compliance level gets set to 9 in the project. This doesn't happen if I don't try to override the formatter. I also get an error message when I try to apply any change to the project in the Properties dialog: "Error: Exception occurred while saving project preferences: /my-project/.settings/org.eclipse.jdt.ui.prefs."

Here is what I've tried so far:

task eclipseConfig {
    group='eclipse'
    dependsOn cleanEclipse
    dependsOn cleanEclipseWtp
    dependsOn tasks['eclipse']
    dependsOn eclipseWtp

    // .settings directory may not exist yet
    file('.settings').mkdir()

    // Attempt to configure Eclipse to use our custom Java formatter
    File f = file('.settings/org.eclipse.jdt.core.prefs')
    f.write('eclipse.preferences.version=1\n')
    def settings = new XmlSlurper().parse(rootProject.file('formatters/eclipse-java-formatter.xml')).profile.setting
    for(def setting : settings) {
        f.append("${setting['@id']}=${setting['@value']}\n")
    }
    f.append('org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter')

    // Another attempt to configure Eclipse to use our custom Java formatter
    f = file('.settings/org.eclipse.jdt.ui.prefs')
    f.write('eclipse.preferences.version=1\n')
    f.append('org.eclipse.jdt.ui.formatterprofiles=')
    f.append(rootProject.file('formatters/eclipse-java-formatter.xml').text
            .replaceAll(~/\r*\n/, '\\\\r\\\\n').replaceAll('=', '\\\\='))
    f.append('\nformatter_profile=_Custom Java Styles')
}

Any help is greatly appreciated.


Solution

  • You are in the right direction: The formatting and cleanup configuration stays in the org.eclipse.jdt.core.prefs and org.eclipse.jdt.ui.prefs files within the .settings directory. But I wouldn't dare to mess up with these files' contents line by line, because they follow Eclipse's own proprietary format, which I doubt is well documented nor guranteed to remain unchanged in time.

    Instead, I would configure the format and cleanup of one dummy project from within Eclipse, then copy the full content (not line by line) of each of these file to your gradle project, and make the gradle script pasting completely each one of them when exporting a new project to Eclipse. By copying and pasting the full files as Eclipse created it, you will avoid semantic errors like the one you are experimenting.

    Anyway, if you still want to process these files line by line, I think the cause of your current error is that you forget some of these declarations:

    • org.eclipse.jdt.core.prefs: org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
    • org.eclipse.jdt.core.prefs: org.eclipse.jdt.core.compiler.compliance=1.8
    • org.eclipse.jdt.core.prefs: org.eclipse.jdt.core.compiler.source=1.8
    • org.eclipse.wst.common.project.facet.core.xml: <installed facet="java" version="1.8"/>