Skip to content

GraalVM native image cannot analyze projects: NoSuchFieldError: variables (JavaParser reflection metadata gap) #153

Description

@rahlk
Summary
-------
The GraalVM native image (./gradlew nativeCompile) builds successfully, but the
resulting `codeanalyzer` native binary cannot analyze any project. Every run that
performs source analysis fails at startup with a JavaParser reflection error.

Environment
-----------
- GraalVM CE 21.0.2 (native-image 21.0.2)
- graalvmNative gradle plugin 0.10.4, built with --no-fallback
- Binary: build/native/nativeCompile/codeanalyzer (approx 63 MB)

Steps to reproduce
------------------
1. Install a GraalVM with native-image (e.g. sdk install java 21.0.2-graalce).
2. ./gradlew nativeCompile
3. ./build/native/nativeCompile/codeanalyzer -i <any-java-project> --emit json -a 1

Expected
--------
analysis.json is produced, same as `java -jar codeanalyzer.jar -i <proj> --emit json -a 1`.

Actual
------
Exception in thread "main" java.lang.NoSuchFieldError: variables
    at com.github.javaparser.metamodel.PropertyMetaModel.getValue(PropertyMetaModel.java:263)
    at com.github.javaparser.ast.validator.language_level_validations.chunks.CommonValidators.lambda$new$7(CommonValidators.java:78)
    at com.github.javaparser.ast.validator.TreeVisitorValidator.accept(TreeVisitorValidator.java:38)
    at com.github.javaparser.ast.validator.Validators.accept(Validators.java:63)
    at com.github.javaparser.ParserConfiguration$2.postProcess(ParserConfiguration.java:340)
    at com.github.javaparser.JavaParser.parse(JavaParser.java:128)
    at com.github.javaparser.symbolsolver.utils.SymbolSolverCollectionStrategy.collect(SymbolSolverCollectionStrategy.java:70)
    at com.ibm.cldk.SymbolTable.extractAll(SymbolTable.java:1200)
    at com.ibm.cldk.CodeAnalyzer.analyze(CodeAnalyzer.java:236)
    at com.ibm.cldk.CodeAnalyzer.run(CodeAnalyzer.java:153)
    at com.ibm.cldk.CodeAnalyzer.main(CodeAnalyzer.java:134)

Root cause
----------
JavaParser drives its AST validators through a reflective metamodel:
PropertyMetaModel.getValue uses reflective Field access on AST node fields such as
`variables`. Under the native-image model these classes and fields
must be registered for reflection at build time. The project reflection config
(src/main/resources/META-INF/native-image-config/reflect-config.json) does not
cover the JavaParser AST node classes and their declared fields, so the lookup of
the `variables` field throws NoSuchFieldError at runtime.

Suggested fix
-------------
Regenerate / extend the native reflection metadata for JavaParser:

1. Run the GraalVM tracing agent against a representative analysis run and merge
   the captured config:
     java -agentlib:native-image-agent=config-merge-dir=src/main/resources/META-INF/native-image-config \
       -jar build/libs/codeanalyzer.jar -i <sample-project> --emit json -a 2
   This captures the reflection/resource/proxy/JNI entries the parser needs.

2. And/or hand-add the JavaParser AST classes (com.github.javaparser.ast.**) with
   allDeclaredFields to reflect-config.json.

3. Add a native smoke test in CI that runs the native binary with --emit json on a
   tiny fixture, so this regression is caught going forward.

Impact
------
- The native build itself succeeds; this is purely a runtime reflection gap.
- Blocks all native-image analysis, including --emit json and --emit neo4j end to
  end. The fat jar (java -jar) is unaffected.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions