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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions