ECJ based parsing - SonarSource/sonar-java GitHub Wiki

Context

Since version 6.0.0 of the Java analyzer (December 2019), the parsing of java source files is done using the Eclipse Compiler for Java (ECJ), itself shipped as part of the eclipse JDT Core project from the eclipse foundation.

Ultimately, this means that the java analyzer's capacity to parse a given version of Java depends merely on the capacity of the eclipse compiler itself to parse this version. In other words, the support of new versions of java depends on the release lifecycle of the JDT.

Embedding JDT into sonar-java

The core part of Eclipse's Java Development Tools (JDT-core) is developed for its own purpose inside the eclipse IDE: compiling code and providing warnings in the IDE. In order to write the sonar-java static analyzer, independent from eclipse, we need to be able to access some parts of the eclipse compiler that are not exposed. Consequently, the sonar-java project contains a dedicated module whose responsibility is to shade a given version of JDT and embed it into the sonar-java project. See sonar-java/jdt/pom.xml.

About eclipse releases

  • The eclipse foundation follows a strict lifecycle with simultaneous releases across all their projects every 3 months: In March, June, September, and December. The dedicated page can be found here: eclipse - Simultaneous Release.
  • Every new eclipse release is accompanied by the publishment of a "New & Noteworthy" page, that describes changes. It contains a dedicated page for the JDT, listing changes that might impact the java analyzer itself. They notably announce at this place the support of new versions of Java. For example, the support of java 19 is announced (under special conditions, see below) for version 4.25 of the JDT
  • Only released versions of the JDT reach maven central, and it is not following the numbering of eclipse IDE release. For instance, release 4.25 of eclipse (2022-09) embeds JDT-core 3.31.

Java release lifecycle versus eclipse lifecycle

The Java release pace increased over the past years, reaching a state where a new version of the language is released every 6 months: in March and September. The release dates can be found here: java.com/releases/.

As a consequence, releases of eclipse happening in March and September are usually conflicting schedule with the release of a new Java version. The eclipse foundation releasing BEFORE java, causing a lag: They release a new version of eclipse WITHOUT support of the java version which has just been released. Consequently, only the next version of eclipse will embed the support of the new version of java. On the sonar-java analyzer side, this means that we can not offer our users the support of the new java version immediately after its release. We have to wait 3 months (minimum) for the next eclipse version.

Example of release lag:

  1. 08/09/2022: Release of eclipse 4.25 (2022-09)
    1. Does not support Java 19 officially, because not yet released, but it can be achieved through marketplace upgrade
  2. 20/09/2022: Release of JDK 19
  3. 07/12/2022: Release of eclipse 4.26 (2022-12)
    1. Brings official support for Java 19

From September 20th until December 7th, we wait for the official support for Java 19.

Supporting a new version of Java once supported by JDT-core

TODO

Support not yet released but already part of jdt-core code?

https://github.com/eclipse-jdt/eclipse.jdt.core

Building JDT locally

https://github.com/eclipse-platform/eclipse.platform.releng.aggregator

Extracting SNAPSHOT dependencies in a local repository

https://github.com/SonarSource/sonar-java/pull/4218/files#diff-3649cadce0b6dd72ff25b246973c78c782991b6922cc1ec6e626566cccfe79ad

libs
└── org
    └── eclipse
        ├── eclipse-platform-parent
        │   └── 4.26.0-SNAPSHOT
        │       └── eclipse-platform-parent-4.26.0-SNAPSHOT.pom
        ├── jdt
        │   ├── eclipse.jdt.core
        │   │   └── 4.26.0-SNAPSHOT
        │   │       └── eclipse.jdt.core-4.26.0-SNAPSHOT.pom
        │   └── org.eclipse.jdt.core
        │       └── 3.32.0-SNAPSHOT
        │           ├── org.eclipse.jdt.core-3.32.0-SNAPSHOT-antadapter.jar
        │           ├── org.eclipse.jdt.core-3.32.0-SNAPSHOT-batch-compiler.jar
        │           ├── org.eclipse.jdt.core-3.32.0-SNAPSHOT-batch-compiler-src.jar
        │           ├── org.eclipse.jdt.core-3.32.0-SNAPSHOT.jar
        │           ├── org.eclipse.jdt.core-3.32.0-SNAPSHOT.pom
        │           └── org.eclipse.jdt.core-3.32.0-SNAPSHOT-sources.jar
        └── platform
            ├── eclipse.platform
            │   └── 4.26.0-SNAPSHOT
            │       └── eclipse.platform-4.26.0-SNAPSHOT.pom
            ├── eclipse.platform.resources
            │   └── 4.26.0-SNAPSHOT
            │       └── eclipse.platform.resources-4.26.0-SNAPSHOT.pom
            ├── eclipse.platform.runtime
            │   └── 4.26.0-SNAPSHOT
            │       └── eclipse.platform.runtime-4.26.0-SNAPSHOT.pom
            ├── eclipse.platform.text
            │   └── 4.26.0-SNAPSHOT
            │       └── eclipse.platform.text-4.26.0-SNAPSHOT.pom
            ├── org.eclipse.core.contenttype
            │   └── 3.8.200-SNAPSHOT
            │       ├── org.eclipse.core.contenttype-3.8.200-SNAPSHOT.jar
            │       ├── org.eclipse.core.contenttype-3.8.200-SNAPSHOT.pom
            │       └── org.eclipse.core.contenttype-3.8.200-SNAPSHOT-sources.jar
            ├── org.eclipse.core.jobs
            │   └── 3.13.200-SNAPSHOT
            │       ├── org.eclipse.core.jobs-3.13.200-SNAPSHOT.jar
            │       ├── org.eclipse.core.jobs-3.13.200-SNAPSHOT.pom
            │       └── org.eclipse.core.jobs-3.13.200-SNAPSHOT-sources.jar
            ├── org.eclipse.core.resources
            │   └── 3.18.100-SNAPSHOT
            │       ├── org.eclipse.core.resources-3.18.100-SNAPSHOT.jar
            │       ├── org.eclipse.core.resources-3.18.100-SNAPSHOT.pom
            │       └── org.eclipse.core.resources-3.18.100-SNAPSHOT-sources.jar
            ├── org.eclipse.core.runtime
            │   └── 3.26.100-SNAPSHOT
            │       ├── org.eclipse.core.runtime-3.26.100-SNAPSHOT.jar
            │       ├── org.eclipse.core.runtime-3.26.100-SNAPSHOT.pom
            │       └── org.eclipse.core.runtime-3.26.100-SNAPSHOT-sources.jar
            ├── org.eclipse.equinox.common
            │   └── 3.16.200
            │       ├── org.eclipse.equinox.common-3.16.200.jar
            │       ├── org.eclipse.equinox.common-3.16.200.pom
            │       └── org.eclipse.equinox.common-3.16.200-sources.jar
            ├── org.eclipse.equinox.preferences
            │   └── 3.10.100
            │       ├── org.eclipse.equinox.preferences-3.10.100.jar
            │       ├── org.eclipse.equinox.preferences-3.10.100.pom
            │       └── org.eclipse.equinox.preferences-3.10.100-sources.jar
            ├── org.eclipse.osgi
            │   └── 3.18.100
            │       ├── org.eclipse.osgi-3.18.100.jar
            │       ├── org.eclipse.osgi-3.18.100.pom
            │       └── org.eclipse.osgi-3.18.100-sources.jar
            ├── org.eclipse.text
            │   └── 3.12.300-SNAPSHOT
            │       ├── org.eclipse.text-3.12.300-SNAPSHOT.jar
            │       ├── org.eclipse.text-3.12.300-SNAPSHOT.pom
            │       └── org.eclipse.text-3.12.300-SNAPSHOT-sources.jar
            ├── resources-bundles
            │   └── 4.26.0-SNAPSHOT
            │       └── resources-bundles-4.26.0-SNAPSHOT.pom
            └── runtime-bundles
                └── 4.26.0-SNAPSHOT
                    └── runtime-bundles-4.26.0-SNAPSHOT.pom

Updating JParser, adding tests etc.