Compilation error after upgrading to JDK 21 - NoSuchFieldError JCImport does not have member field JCTree qualid
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
The NoSuchFieldError: JCImport does not have member field JCTree qualid error occurs because JDK 21 refactored the internal com.sun.tools.javac.tree.JCTree AST classes. Specifically, JCImport.qualid was replaced with a new accessor method as part of JEP 441/pattern-matching changes. The fix is almost always to upgrade Lombok, Mapstruct, Error Prone, or whichever annotation processor or compiler plugin is accessing that internal field.
What Changed in JDK 21
The com.sun.tools.javac.tree package is the internal Abstract Syntax Tree representation used by javac. These classes are not part of the public Java SE API. They live in the jdk.compiler module and are subject to change without notice between JDK releases.
In JDK 21, the JCImport node was restructured:
Any library that accessed jcImport.qualid directly via reflection or bytecode manipulation will throw NoSuchFieldError at compile time or runtime on JDK 21.
Which Libraries Are Affected
The most commonly affected libraries:
| Library | Affected Versions | Fixed Version | Notes |
| Lombok | < 1.18.30 | 1.18.30+ | Most common cause of this error |
| MapStruct | < 1.5.5 | 1.5.5+ | Annotation processor |
| Error Prone | < 2.23.0 | 2.23.0+ | Google's static analysis tool |
| Checker Framework | < 3.39.0 | 3.39.0+ | Type-checking annotation processor |
| Immutables | < 2.10.0 | 2.10.0+ | Code generation library |
| OpenJDK Nashorn | < 15.4 | 15.4+ | JavaScript engine |
Fix: Upgrade the Offending Library
Identifying Which Library Causes the Error
The stack trace tells you which library is accessing the internal API. Look for the class name right before the NoSuchFieldError:
In this example, Lombok is the culprit.
Fix for Lombok (Most Common)
Maven:
Gradle (Kotlin DSL):
Gradle (Groovy DSL):
Fix for MapStruct
Fix for Error Prone
Diagnosing in Multi-Module Projects
In large projects with many dependencies, multiple libraries may access javac internals. Use this approach to find all potentially affected dependencies:
For Gradle:
If You Cannot Upgrade the Library
In rare cases, the library may not yet have a JDK 21-compatible release. Options:
Option 1: Pin JDK Version
Stay on JDK 17 or 20 until the library publishes a fix. Use a .sdkmanrc or toolchains.xml to enforce this:
Option 2: Add JVM Flags to Open Internal Modules
Some libraries work if you explicitly open the jdk.compiler module. Add these to your build:
In Maven:
This may suppress the IllegalAccessError but will not fix NoSuchFieldError since the field genuinely does not exist. This workaround only helps if the issue is access restriction, not a missing field.
Option 3: Fork and Patch
If the library is open source and unmaintained, fork the repository, update the internal API calls, and publish to your local Maven repository. This is a last resort.
Preventing This in Future JDK Upgrades
The root cause is dependency on internal com.sun.* APIs. To avoid this pattern:
- Audit dependencies before upgrading. Run your build against the new JDK in CI before committing to the upgrade.
- Subscribe to library release notes. Lombok, MapStruct, and Error Prone all publish JDK compatibility matrices in their documentation.
- Check
jdepsfor internal API usage. Thejdepstool can identify dependencies on internal APIs:
- Adopt JDK LTS releases conservatively. JDK 21 is an LTS release. Library maintainers typically prioritize LTS compatibility, so waiting 2-3 months after an LTS release gives most libraries time to update.
Common Pitfalls
- Upgrading JDK without upgrading annotation processors. The JDK and annotation processor versions must be compatible. Always check the compatibility matrix before upgrading.
- Transitive dependency pulling in an old version. You may have Lombok 1.18.34 in your POM, but a transitive dependency forces an older version. Use
mvn dependency:treeorgradle dependenciesto verify the resolved version. - IDE using a different JDK than the build. IntelliJ or Eclipse may compile with a different JDK than Maven/Gradle. Ensure IDE project SDK matches the build tool configuration.
- Confusing
NoSuchFieldErrorwithNoSuchMethodError. Both indicate internal API changes, but the fix is the same: upgrade the library. - Using
--add-opensas a permanent fix. Module-opening flags are a band-aid. They do not fix missing fields and they weaken the module system's encapsulation guarantees. Always prefer upgrading the library.
Summary
- The
NoSuchFieldError: JCImport does not have member field JCTree qualiderror is caused by JDK 21 removing thequalidfield from javac's internal AST classes. - The fix is to upgrade the annotation processor or compiler plugin that accesses this field. Lombok >= 1.18.30 and MapStruct >= 1.5.5 include the fix.
- Use
mvn dependency:treeorgradle dependenciesto identify the exact library and version causing the error. - Do not rely on
--add-opensJVM flags as a permanent solution. They cannot restore a field that no longer exists. - Before future JDK upgrades, audit your dependencies with
jdeps --jdk-internalsand check library compatibility matrices.
Related reading
- Compile error Class file has wrong version 52.0, should be 50.0
- CompletableFuture in loop How to collect all responses and handle errors
- CompletableFuture not working as expected
- CompletableFuture thenApply vs thenCompose
- CompletableFuture vs Async
- CompletableFuture vs Spring Transactions
- CompletableFutureT class join vs get
- Computational Complexity of TreeSet methods in Java

OOD Fundamentals
Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.