Skip to content

Add support for Annotation Processors in the Javac Extension#3686

Open
PiIsRational wants to merge 16 commits intoKeYProject:mainfrom
PiIsRational:javac-extension
Open

Add support for Annotation Processors in the Javac Extension#3686
PiIsRational wants to merge 16 commits intoKeYProject:mainfrom
PiIsRational:javac-extension

Conversation

@PiIsRational
Copy link
Contributor

@PiIsRational PiIsRational commented Nov 18, 2025

Changes

Extended the Javac Extension to be able to load annotation processors, while the java code is getting checked
in KeY. This includes creating settings for the Javac Extension, to be able to set the checkers.
Also, the there are changes to the run step of the gradle script
to add (add-export and add-opens) directives to the java runtime such that annotations processors can access the internal java compiler data structures.
This is required to be done by hand when using KeY as a jar and would require the following (or similar) command:

java \
    --add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \
    --add-exports jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED \
    --add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \
    --add-exports jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED \
    --add-exports jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED \
    --add-exports jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED \
    --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \
    --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED \
    --add-opens jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED \
    -jar key-2.12.4-dev-exe.jar

Type of pull request

  • New feature (non-breaking change which adds functionality)
  • There are changes to the (Java) code
  • There are changes to the deployment/CI infrastructure (gradle, github, ...)

Ensuring quality

  • I made sure that introduced/changed code is well documented (javadoc and inline comments).
  • I have tested the feature as follows:
    • I used it with multiple annotation processors
    • I loaded KeY with various settings to check if and when they are deleted
  • I have checked that runtime performance has not deteriorated.

Additional information and contact(s)

@WolframPfeifer is involved in this pull request.

The contributions within this pull request are licensed under GPLv2 (only) for inclusion in KeY.

@codecov
Copy link

codecov bot commented Dec 8, 2025

Codecov Report

❌ Patch coverage is 0% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 50.34%. Comparing base (e5853a5) to head (7c4df33).
⚠️ Report is 95 commits behind head on main.

Files with missing lines Patch % Lines
...n/java/de/uka/ilkd/key/settings/Configuration.java 0.00% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##               main    #3686      +/-   ##
============================================
+ Coverage     47.98%   50.34%   +2.35%     
+ Complexity    16045    15902     -143     
============================================
  Files          1683     1597      -86     
  Lines         96046    91024    -5022     
  Branches      15388    14553     -835     
============================================
- Hits          46091    45823     -268     
+ Misses        44683    39988    -4695     
+ Partials       5272     5213      -59     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@PiIsRational PiIsRational changed the title Javac extension Add support for Annotation Processors in the Javac Extension Jan 26, 2026
@WolframPfeifer WolframPfeifer added GUI Feature New feature or request Java Pull requests that update Java code labels Jan 26, 2026
@WolframPfeifer WolframPfeifer added this to the v3.0.0 milestone Jan 26, 2026
@wadoon
Copy link
Member

wadoon commented Jan 26, 2026

One solution to the exports-problem is to start javac in an external process. This means:

  1. Writing a main function inside KeY
  2. On call, use the current classpath and JRE, and start a new Java process which enters the new main function.
  3. Capture the diagnostics in the new process, and send them in a structured way to stdout.
  4. Read the stdout in the process spawner.

@PiIsRational PiIsRational marked this pull request as ready for review February 23, 2026 17:15
Copy link
Member

@WolframPfeifer WolframPfeifer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this PR, which will allow running Checker Framework checkers (e.g. for Nullness of Ownership) from the KeY GUI directly.

Also, thanks to @wadoon for the initial draft of the external checker, and @PiIsRational for polishing.

I have a few minor complaints about the use of var. When these are fixed, the PR would be ready from my point of view. Also, there is code smell in the unit test (check without assert), but we could also keep it like that.

*/
public static void main(String[] args) {
try (var input = new InputStreamReader(System.in)) {
var params = Configuration.load(CharStreams.fromReader(input));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have the policy that the var keyword can be used in the code as long as the type is obvious (for example, when calling a constructor), otherwise it would decrease readability of the code. In this case, it is not in my opinion. Can you please make the type here explicit?

var settings = new JavacSettings();
settings.readSettings(params);

var result = check(null,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above: Make the type explicit for better readability please.


// the KeY logging messages from `process` (currently not used)
var logs = Streams.toString(process.getInputStream());
var messages = Configuration.load(CharStreams.fromStream(process.getErrorStream()));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here as well ...

}

@Test
void compileExternal() throws ExecutionException, InterruptedException {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my opinion, it is a bit of a code smell to have a test without any asserts (was already the case for the original test of this class). However, this can still count as some kind of smoke test, so I do not let it block the merge ...

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

Labels

Feature New feature or request GUI Java Pull requests that update Java code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants