question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Indexed `provided` annotation breaks `build` goal (or app startup) in 2.14

See original GitHub issue

Describe the bug

While trying to upgrade from 2.13.3 to 2.14.0/1 I was greeted with a strange java.lang.ClassNotFoundException: lombok.NonNull very early in the boot process of the app.

This is in a multi-module project that is working just fine with Quarkus 2.13.3 (and the “old” Jandex 1.2.3).

In a non-app module, a class is using lombok.NonNull on a field alongside lombok.RequiredArgsConstructor. jandex-maven-plugin is executed in the module to provide an index. The lombok jar is a provided dependency (as recommended generally). See the reproducer further down.

Expected behavior

Should work as in 2.13

Actual behavior

Fails at app startup (with ECJ) or already when building the app via build goal (with standard compiler).

How to Reproduce?

q_jandex_nonnull.zip

mvn clean verify:

[INFO] --- quarkus-maven-plugin:2.14.1.Final:build (default) @ code-with-quarkus-app ---
[WARNING] [io.quarkus.arc.processor.BeanArchives] Failed to index lombok.NonNull: Class does not exist in ClassLoader QuarkusClassLoader:Deployment Class Loader: PROD@65f470f8
[INFO] [io.quarkus.arc.processor.IndexClassLookupUtils] Class for name: lombok.NonNull was not found in Jandex index. Please ensure the class is part of the index.
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary for code-with-quarkus 1.0.0-SNAPSHOT:
[INFO] 
[INFO] code-with-quarkus .................................. SUCCESS [  0.027 s]
[INFO] code-with-quarkus-lib .............................. SUCCESS [  0.924 s]
[INFO] code-with-quarkus-app .............................. FAILURE [  1.511 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  2.968 s
[INFO] Finished at: 2022-11-22T23:13:14+01:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal io.quarkus:quarkus-maven-plugin:2.14.1.Final:build (default) on project code-with-quarkus-app: Failed to build quarkus application: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
[ERROR] 	[error]: Build step io.quarkus.arc.deployment.ArcProcessor#generateResources threw an exception: java.lang.IllegalStateException: java.util.concurrent.ExecutionException: java.lang.NullPointerException: Annotation class not available: @NonNull
[ERROR] 	at io.quarkus.deployment.ExtensionLoader$3.execute(ExtensionLoader.java:918)
[ERROR] 	at io.quarkus.builder.BuildContext.run(BuildContext.java:281)
[ERROR] 	at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
[ERROR] 	at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2449)
[ERROR] 	at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1478)
[ERROR] 	at java.base/java.lang.Thread.run(Thread.java:833)
[ERROR] 	at org.jboss.threads.JBossThread.run(JBossThread.java:501)
[ERROR] Caused by: java.util.concurrent.ExecutionException: java.lang.NullPointerException: Annotation class not available: @NonNull
[ERROR] 	at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:122)
[ERROR] 	at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:191)
[ERROR] 	at io.quarkus.arc.processor.BeanProcessor.generateResources(BeanProcessor.java:319)
[ERROR] 	at io.quarkus.arc.deployment.ArcProcessor.generateResources(ArcProcessor.java:570)
[ERROR] 	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[ERROR] 	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
[ERROR] 	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[ERROR] 	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
[ERROR] 	at io.quarkus.deployment.ExtensionLoader$3.execute(ExtensionLoader.java:909)
[ERROR] 	... 6 more
[ERROR] Caused by: java.lang.NullPointerException: Annotation class not available: @NonNull
[ERROR] 	at java.base/java.util.Objects.requireNonNull(Objects.java:233)
[ERROR] 	at io.quarkus.arc.processor.AnnotationLiteralProcessor.create(AnnotationLiteralProcessor.java:87)
[ERROR] 	at io.quarkus.arc.processor.BeanGenerator.collectInjectionPointAnnotations(BeanGenerator.java:1937)
[ERROR] 	at io.quarkus.arc.processor.BeanGenerator.wrapCurrentInjectionPoint(BeanGenerator.java:1837)
[ERROR] 	at io.quarkus.arc.processor.BeanGenerator.initConstructor(BeanGenerator.java:704)
[ERROR] 	at io.quarkus.arc.processor.BeanGenerator.createConstructor(BeanGenerator.java:614)
[ERROR] 	at io.quarkus.arc.processor.BeanGenerator.generateClassBean(BeanGenerator.java:355)
[ERROR] 	at io.quarkus.arc.processor.BeanGenerator.generate(BeanGenerator.java:122)
[ERROR] 	at io.quarkus.arc.processor.BeanProcessor$4.call(BeanProcessor.java:258)
[ERROR] 	at io.quarkus.arc.processor.BeanProcessor$4.call(BeanProcessor.java:254)
[ERROR] 	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
[ERROR] 	... 5 more

mvn clean verify -Pquarkus-2.13.4 is fine though (switches from Quarkus 2.14.1 to 2.13.4 and jandex-plugin to the old coordinates and version)

Please note that this reproducer is not using ECJ (unlike my actual project), hence the error at build time, not boot time. If required I can provide a ECJ setup like in https://github.com/smallrye/jandex/issues/268. I actually started with an ECJ setup, stripped it down and was then surprised by the different behavior.

Output of uname -a or ver

No response

Output of java -version

17.0.5

GraalVM version (if different from Java)

No response

Quarkus version or git rev

2.14.1

Build tool (ie. output of mvnw --version or gradlew --version)

No response

Additional information

I think it’s an issue in Jandex (cc @Ladicek), but I’m not entirely sure. Might also be related to Arc (cc @mkouba @manovotn )?

If I had to guess (wildly), I’d suppose that Jandex 3 is more strict about missing annotations.

Please note that there have been discussions about why lombok.NonNull has CLASS retention in the first place: https://github.com/projectlombok/lombok/issues/895 I do think the maintainer has a point though: https://github.com/projectlombok/lombok/issues/895#issuecomment-145653045

Issue Analytics

  • State:closed
  • Created 10 months ago
  • Comments:17 (11 by maintainers)

github_iconTop GitHub Comments

1reaction
famodcommented, Nov 28, 2022

Fix confirmed in 2.14.2! Thanks all, especially @Ladicek .

1reaction
Ladicekcommented, Nov 23, 2022

Yes, I’m not talking about “processing” errors but “semantic” errors (i.e. a class is annotated with a qualifier but the qualifier class is not available).

Okay, so what I’m doing is:

  1. AnnotationLiteralProcessor will still throw if the annotation class is null, and most callers don’t check that. That’s because most callers deal with qualifiers and interceptor bindings, and those must always exist. So if a qualifier class or an interceptor binding class is missing, we’ll still fail. There are 2 places that deal with arbitrary annotations on injection points, and those will just check if the annotation class exists or not.
  2. This is an extra and we wouldn’t really have to do it, but I think we want to: AnnotationLiteralProcessor will additionally throw if the annotation is class-retained. Again, most callers deal with qualifiers and interceptor bindings, and those must always be runtime-retained. So if a qualifier or interceptor binding is class-retained, we’ll fail. I think that’s good. The same 2 places mentioned in previous item are modified to just skip class-retained annotations.

WDYT?

EDIT: if you want to see the code, it’s here: https://github.com/Ladicek/quarkus/commits/filter-annotation-literals I want to run CI first in my fork before opening a PR.

Might be an unpopular opinion but given it’s a very new feature, if we think it was a bad decision and we want to fix it, it’s probably still possible if we document it properly in the announcement. I don’t think it’s widely used in the wild. Better than live with it forever.

That sounds sensible. I’ll see if I can come up with a better API.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Writing Your Own Extension - Quarkus
Quarkus extensions add a new developer focused behavior to the core offering, and consist of two distinct parts, buildtime augmentation and runtime ...
Read more >
Quarkus 2.14.2.Final发布 - Linuxeden开源社区
Quarkus 2.14.2. ... #29425 – Indexed provided annotation breaks build goal (or app startup) in 2.14; #29420 – Skip quarkus:dev for modules ...
Read more >
Improving application startup in Liberty - IBM
You can substantially improve the startup of applications by having Liberty read Jandex index files to obtain class and annotation data for application...
Read more >
JUnit 5 User Guide
The goal of this document is to provide comprehensive reference documentation for programmers writing tests, extension authors, and engine ...
Read more >
Writing R Extensions - The Comprehensive R Archive Network
1 Creating R packages. Packages provide a mechanism for loading optional code, data and documentation as needed. The R distribution itself includes about...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found