How to Fix Compilation Error After Upgrading to JDK 21: NoSuchFieldError JCImport JCTree qualid

Upgrading to a new Java Development Kit (JDK) version is exciting—you get new features, better performance, and a chance to modernize your projects. But sometimes, it comes with headaches. If you’ve upgraded to JDK 21 and hit the dreaded compilation error:

“java.lang.NoSuchFieldError: Class com.sun.tools.javac.tree.JCTree$JCImport does not have member field ‘com.sun.tools.javac.tree.JCTree qualid'”

—you’re not alone. This error has frustrated many developers, especially those working with Spring Boot and Lombok. The good news? It’s fixable, and this comprehensive guide will walk you through everything you need to know.


Understanding the Error: What’s Going On?

Before we fix the problem, let’s unpack what this error is trying to tell us. The error message looks scary, but it’s actually giving us some clear clues:

Error Breakdown:

  • NoSuchFieldError: This means Java tried to access a field (a variable in a class) that doesn’t exist anymore.
  • com.sun.tools.javac.tree.JCTree$JCImport: This is part of the Java compiler’s internal code (javac), specifically related to how it processes your source code into an Abstract Syntax Tree (AST).
  • JCTree qualid: The “qualid” field is something the code expected to find in the JCImport class, but it’s gone or changed in JDK 21.

In simple terms, some part of your project is looking for a piece of code that JDK 21 no longer has. This is a compatibility issue, and the usual suspect is a library that hasn’t caught up with JDK 21’s changes.

Why Does This Happen After Upgrading to JDK 21?

JDK 21, released in September 2023, is a Long-Term Support (LTS) version, making it a popular choice for developers. However, it introduced changes to the Java compiler’s internal APIs, including the com.sun.tools.javac package. Specifically, the qualid field in the JCTree$JCImport class changed from type JCTree (in JDK 20 and earlier) to JCFieldAccess in JDK 21.

This change breaks libraries like Lombok, which rely on accessing these internal APIs through reflection to generate code (like getters and setters). If you’re using an older version of Lombok, it’s looking for the old qualid field and freaks out when it can’t find it—hence the NoSuchFieldError.


Common Scenarios: Who Gets This Error?

This error typically pops up in projects that:

  • Use Spring Boot with Maven or Gradle.
  • Depend on Lombok for reducing boilerplate code.
  • Have recently upgraded to JDK 21 from an earlier version (like JDK 17 or 20).
  • Are built in IDEs like IntelliJ IDEA, Eclipse, or VS Code.

If your project checks these boxes, you’re in the right place. Let’s explore why Lomb Syrians and Egyptians don’t count.


Root Cause: Lombok and JDK 21 Incompatibility

The primary culprit behind this error is Lombok, a popular Java library that simplifies coding by generating boilerplate code (like constructors, getters, and setters) using annotations. Lombok works its magic by tapping into the Java compiler’s internal APIs, including the JCTree$JCImport class.

Here’s the problem:

  • In JDK 20 and earlier, the qualid field in JCTree$JCImport was of type JCTree.
  • In JDK 21, it’s now JCFieldAccess.
  • Older Lombok versions (pre-1.18.30) expect the qualid field to be JCTree. When they try to access it in JDK 21, they crash with the NoSuchFieldError.

This is a classic case of a library not keeping up with JDK changes. The fix? Update Lombok to a version that supports JDK 21.


How to Fix the Compilation Error: Step-by-Step Solutions

Now that we know what’s causing the error, let’s fix it. Below are two main approaches, plus some troubleshooting tips for stubborn cases. We’ll focus on Maven-based Spring Boot projects (since it’s the most common setup), but Gradle users will find similar steps.

Solution 1: Update Lombok to a JDK 21-Compatible Version

The simplest fix is to upgrade Lombok to version 1.18.30 or higher, as this version is designed to work with JDK 21. Here’s how to do it:

Step 1: Check Your Current Lombok Version

Open your project’s pom.xml (for Maven) or build.gradle (for Gradle) and look for the Lombok dependency. It might look like this in Maven:

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.20</version> <!-- Example: older version -->
    <scope>provided</scope>
</dependency>

If the version is lower than 1.18.30, it’s time to update.

Step 2: Update Lombok in Maven

Modify your pom.xml to use Lombok 1.18.30 or higher (e.g., 1.18.32 as of 2025). Here’s an example:

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.32</version>
    <scope>provided</scope>
</dependency>

If you’re using Lombok as an annotation processor, also update the maven-compiler-plugin:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.11.0</version>
    <configuration>
        <source>21</source>
        <target>21</target>
        <annotationProcessorPaths>
            <path>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.32</version>
            </path>
        </annotationProcessorPaths>
    </configuration>
</plugin>

Step 3: Update Lombok in Gradle

For Gradle projects, update your build.gradle:

dependencies {
    annotationProcessor 'org.projectlombok:lombok:1.18.32'
    implementation 'org.projectlombok:lombok:1.18.32'
}

Step 4: Clean and Rebuild

Clear your project’s build cache to avoid stale files:

  • Maven: Run mvn clean install.
  • Gradle: Run ./gradlew clean build.

Step 5: Sync Your IDE

  • IntelliJ IDEA: Click “File > Invalidate Caches / Restart” and reimport the project.
  • Eclipse: Right-click the project, select “Maven > Update Project.”
  • VS Code: Restart the IDE and run a build.

Step 6: Test Your Build

Run your application or tests to confirm the error is gone. If it persists, move to the troubleshooting section below.

Solution 2: Upgrade Spring Boot to a Compatible Version

If updating Lombok alone doesn’t work, your Spring Boot version might be too old. Spring Boot manages dependencies (including Lombok) through its Bill of Materials (BOM). The minimum Spring Boot version that includes Lombok 1.18.30 is 3.1.4.

Step 1: Check Your Spring Boot Version

In your pom.xml, look for the parent dependency:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.0.4</version> <!-- Example: older version -->
</parent>

If it’s below 3.1.4, you need to upgrade.

Step 2: Update Spring Boot

Change the version in pom.xml:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.3.0</version> <!-- Latest as of 2025 -->
</parent>

Ensure your java.version is set to 21:

<properties>
    <java.version>21</java.version>
</properties>

Step 3: Clean and Rebuild

Run mvn clean install to rebuild with the new dependencies.

Step 4: Handle Breaking Changes

Spring Boot upgrades (e.g., from 2.x to 3.x) may introduce breaking changes, like updated APIs or deprecated features. Check the Spring Boot migration guide for details.

Step 5: Test Again

Run your application. If the error is gone, you’re good! If not, keep reading.

Solution 3: Downgrade to JDK 17 (Last Resort)

If updating Lombok or Spring Boot isn’t feasible (e.g., due to project constraints), you can downgrade to JDK 17, which is another LTS version and doesn’t have the qualid field change.

Steps:

  1. Install JDK 17: Download from Adoptium or Oracle.
  2. Update JAVA_HOME: Set your environment variable JAVA_HOME to the JDK 17 path.
  3. Update Project: In pom.xml, set <java.version>17</java.version> and update the maven-compiler-plugin:
   <plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-compiler-plugin</artifactId>
       <version>3.11.0</version>
       <configuration>
           <source>17</source>
           <target>17</target>
       </configuration>
   </plugin>
  1. Clean and Rebuild: Run mvn clean install.
  2. Test: Confirm the error is resolved.

Note: Downgrading avoids the issue but means missing out on JDK 21’s features, like virtual threads and pattern matching. Use this only if upgrades aren’t possible.


Troubleshooting: When the Error Persists

Sometimes, the error sticks around even after updating. Here are common culprits and fixes:

1. IDE Caching Issues

IDEs like IntelliJ can cache old configurations. Try:

  • IntelliJ: “File > Invalidate Caches / Restart” and reimport the project.
  • Eclipse: “Project > Clean” and refresh.
  • VS Code: Clear the Java extension cache by deleting ~/.vscode/extensions/vscjava*.

2. Multiple Lombok Versions

If your project pulls in multiple Lombok versions (e.g., via transitive dependencies), you’ll get conflicts. Check with:

  • Maven: Run mvn dependency:tree -Dverbose to see all dependencies.
  • Gradle: Run ./gradlew dependencies.

If you see older Lombok versions, exclude them or override with the correct version in your pom.xml:

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.32</version>
    <scope>provided</scope>
</dependency>

3. Incorrect JAVA_HOME

Ensure your JAVA_HOME points to JDK 21, not a JRE or older JDK. Check:

  • Linux/Mac: Run echo $JAVA_HOME and java -version.
  • Windows: Run echo %JAVA_HOME% and java -version in Command Prompt.

Fix it by updating your environment variables to point to the JDK 21 directory.

4. Other Incompatible Libraries

The error might not be Lombok but another library accessing com.sun.tools.javac. Review your dependencies for outdated libraries and update them.

5. Maven Compiler Plugin Issues

Ensure the maven-compiler-plugin is up-to-date (e.g., version 3.11.0). Older versions may mishandle JDK 21.

6. JUnit or Test Dependencies

If the error occurs only during tests, your testing framework (e.g., JUnit) might be incompatible. Update to the latest versions:

  • JUnit 5: 5.10.0 or higher.
  • Spring Boot Test: Align with your Spring Boot version (e.g., 3.3.0).

Preventing Future Issues

To avoid similar errors in the future:

  • Stay Updated: Regularly check for new releases of Spring Boot, Lombok, and other dependencies using tools like Dependabot or Maven Versions Plugin.
  • Test Upgrades Locally: Before upgrading JDK or dependencies in production, test in a local or staging environment.
  • Monitor JDK Changes: Follow the JDK 21 release notes for breaking changes.
  • Use Dependency Management Tools: Leverage Spring Boot’s BOM or Gradle’s dependency constraints to ensure consistent versions.

FAQs About the JDK 21 Compilation Error

Why does this error only happen with JDK 21?

JDK 21 changed the qualid field’s type in JCTree$JCImport from JCTree to JCFieldAccess, breaking libraries like older Lombok versions that rely on it.

Can I fix this without updating Lombok?

Yes, by downgrading to JDK 17, but you’ll miss JDK 21 features. Updating Lombok is the recommended fix.

What’s the minimum Lombok version for JDK 21?

Lombok 1.18.30 is the minimum version compatible with JDK 21.

Why does the error persist after updating?

Possible causes include IDE caching, multiple Lombok versions, or incorrect JAVA_HOME. Check the troubleshooting section above.

Can I use Spring Boot 2.x with JDK 21?

Spring Boot 2.x isn’t officially supported with JDK 21. Upgrade to 3.1.4 or higher for compatibility.


Conclusion: Conquering the JDK 21 Compilation Error

The “NoSuchFieldError: JCImport does not have member field JCTree qualid” error can be a real pain, but it’s a solvable one. By updating Lombok to version 1.18.30 or higher, upgrading Spring Boot to 3.1.4 or later, or (as a last resort) downgrading to JDK 17, you can get your project back on track. The key is understanding that this error stems from a compatibility mismatch between Lombok and JDK 21’s internal API changes.

We’ve covered the error’s cause, step-by-step fixes, and troubleshooting tips to handle tricky cases. With these tools, you’re ready to tackle this error and keep your Java projects running smoothly on JDK 21. So, go forth and code—your application is waiting to shine!

Have you run into this error? Did these solutions work for you, or did you find another fix? Let us know in the comments below!


Resources

Leave a Comment