Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev mode fails discovering a bean in external jar (gradle/kotlin) #35865

Open
verliba opened this issue Sep 12, 2023 · 16 comments
Open

Dev mode fails discovering a bean in external jar (gradle/kotlin) #35865

verliba opened this issue Sep 12, 2023 · 16 comments
Labels

Comments

@verliba
Copy link

verliba commented Sep 12, 2023

Describe the bug

@Dependent
class MyBean {

on one side, in a jar, with beans.xml (and/or jandex)

@ApplicationScoped
@Startup
class MainBean {
    @Inject
    lateinit var bm: MyBean

    @PostConstruct
    fun doSth() {
        bm.doSth()
    }
}

on the other side..
I can run it like this..

$ java -jar build/QuarkusTest-1.0.0-runner.jar 
MyBean.doSth
__  ____  __  _____   ___  __ ____  ______ 
 --/ __ \/ / / / _ | / _ \/ //_/ / / / __/ 
 -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \   
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/   

but when I run

./gradlew quarkusDev

I get a lot of red output..

Listening for transport dt_socket at address: 5005
Press [e] to edit command line args (currently ''), [h] for more options>
Tests paused
Press [e] to edit command line args (currently ''), [r] to resume testing, [h] for more options>
Press [e] to edit command line args (currently ''), [r] to resume testing, [o] Toggle test output, [h] for more options>
2023-09-12 10:31:55,455 WARN  [io.qua.arc.pro.BeanArchives] (build-13) Failed to index com.test.MyBean: Class does not exist in ClassLoader QuarkusClassLoader:Deployment Class Loader: DEV@667a738
2023-09-12 10:31:55,462 WARN  [io.qua.arc.pro.Methods] (build-13) Parameter type info not available: com.test.MyBean - unable to validate the parameter type's visibility for method setBm declared on com.test.qk.MainBean
2023-09-12 10:31:55,466 INFO  [io.qua.dep.dev.IsolatedDevModeMain] (main) Attempting to start live reload endpoint to recover from previous Quarkus startup failure
2023-09-12 10:31:55,496 ERROR [io.qua.dep.dev.IsolatedDevModeMain] (main) Failed to start quarkus: java.lang.RuntimeException: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
        [error]: Build step io.quarkus.arc.deployment.ArcProcessor#validate threw an exception: jakarta.enterprise.inject.spi.DeploymentException: jakarta.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type com.test.MyBean and qualifiers [@Default]
        - java member: com.test.qk.MainBean#bm
        - declared on CLASS bean [types=[com.test.qk.MainBean, java.lang.Object], qualifiers=[@Default, @Any], target=com.test.qk.MainBean]
        at io.quarkus.arc.processor.BeanDeployment.processErrors(BeanDeployment.java:1447)
        at io.quarkus.arc.processor.BeanDeployment.init(BeanDeployment.java:311)
        at io.quarkus.arc.processor.BeanProcessor.initialize(BeanProcessor.java:158)
        at io.quarkus.arc.deployment.ArcProcessor.validate(ArcProcessor.java:469)
        at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
        at java.base/java.lang.reflect.Method.invoke(Method.java:578)
        at io.quarkus.deployment.ExtensionLoader$3.execute(ExtensionLoader.java:858)
        at io.quarkus.builder.BuildContext.run(BuildContext.java:282)
        at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
        at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2513)
        at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1538)
        at java.base/java.lang.Thread.run(Thread.java:1589)
        at org.jboss.threads.JBossThread.run(JBossThread.java:501)
Caused by: jakarta.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type com.test.MyBean and qualifiers [@Default]
        - java member: com.test.qk.MainBean#bm
        - declared on CLASS bean [types=[com.test.qk.MainBean, java.lang.Object], qualifiers=[@Default, @Any], target=com.test.qk.MainBean]
        at io.quarkus.arc.processor.Beans.resolveInjectionPoint(Beans.java:477)
        at io.quarkus.arc.processor.BeanInfo.init(BeanInfo.java:624)
        at io.quarkus.arc.processor.BeanDeployment.init(BeanDeployment.java:299)
        ... 11 more

        at io.quarkus.runner.bootstrap.AugmentActionImpl.runAugment(AugmentActionImpl.java:336)
        at io.quarkus.runner.bootstrap.AugmentActionImpl.createInitialRuntimeApplication(AugmentActionImpl.java:253)
        at io.quarkus.runner.bootstrap.AugmentActionImpl.createInitialRuntimeApplication(AugmentActionImpl.java:60)
        at io.quarkus.deployment.dev.IsolatedDevModeMain.firstStart(IsolatedDevModeMain.java:82)
        at io.quarkus.deployment.dev.IsolatedDevModeMain.accept(IsolatedDevModeMain.java:423)
        at io.quarkus.deployment.dev.IsolatedDevModeMain.accept(IsolatedDevModeMain.java:55)
        at io.quarkus.bootstrap.app.CuratedApplication.runInCl(CuratedApplication.java:138)
        at io.quarkus.bootstrap.app.CuratedApplication.runInAugmentClassLoader(CuratedApplication.java:93)
        at io.quarkus.deployment.dev.DevModeMain.start(DevModeMain.java:131)
        at io.quarkus.deployment.dev.DevModeMain.main(DevModeMain.java:62)
Caused by: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
        [error]: Build step io.quarkus.arc.deployment.ArcProcessor#validate threw an exception: jakarta.enterprise.inject.spi.DeploymentException: jakarta.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type com.test.MyBean and qualifiers [@Default]
        - java member: com.test.qk.MainBean#bm
        - declared on CLASS bean [types=[com.test.qk.MainBean, java.lang.Object], qualifiers=[@Default, @Any], target=com.test.qk.MainBean]
        at io.quarkus.arc.processor.BeanDeployment.processErrors(BeanDeployment.java:1447)
        at io.quarkus.arc.processor.BeanDeployment.init(BeanDeployment.java:311)
        at io.quarkus.arc.processor.BeanProcessor.initialize(BeanProcessor.java:158)
        at io.quarkus.arc.deployment.ArcProcessor.validate(ArcProcessor.java:469)
        at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
        at java.base/java.lang.reflect.Method.invoke(Method.java:578)
        at io.quarkus.deployment.ExtensionLoader$3.execute(ExtensionLoader.java:858)
        at io.quarkus.builder.BuildContext.run(BuildContext.java:282)
        at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
        at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2513)
        at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1538)
        at java.base/java.lang.Thread.run(Thread.java:1589)
        at org.jboss.threads.JBossThread.run(JBossThread.java:501)
Caused by: jakarta.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type com.test.MyBean and qualifiers [@Default]
        - java member: com.test.qk.MainBean#bm
        - declared on CLASS bean [types=[com.test.qk.MainBean, java.lang.Object], qualifiers=[@Default, @Any], target=com.test.qk.MainBean]
        at io.quarkus.arc.processor.Beans.resolveInjectionPoint(Beans.java:477)
        at io.quarkus.arc.processor.BeanInfo.init(BeanInfo.java:624)
        at io.quarkus.arc.processor.BeanDeployment.init(BeanDeployment.java:299)
        ... 11 more

        at io.quarkus.builder.Execution.run(Execution.java:123)
        at io.quarkus.builder.BuildExecutionBuilder.execute(BuildExecutionBuilder.java:79)
        at io.quarkus.deployment.QuarkusAugmentor.run(QuarkusAugmentor.java:160)
        at io.quarkus.runner.bootstrap.AugmentActionImpl.runAugment(AugmentActionImpl.java:332)
        ... 9 more
Caused by: jakarta.enterprise.inject.spi.DeploymentException: jakarta.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type com.test.MyBean and qualifiers [@Default]
        - java member: com.test.qk.MainBean#bm
        - declared on CLASS bean [types=[com.test.qk.MainBean, java.lang.Object], qualifiers=[@Default, @Any], target=com.test.qk.MainBean]
        at io.quarkus.arc.processor.BeanDeployment.processErrors(BeanDeployment.java:1447)
        at io.quarkus.arc.processor.BeanDeployment.init(BeanDeployment.java:311)
        at io.quarkus.arc.processor.BeanProcessor.initialize(BeanProcessor.java:158)
        at io.quarkus.arc.deployment.ArcProcessor.validate(ArcProcessor.java:469)
        at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
        at java.base/java.lang.reflect.Method.invoke(Method.java:578)
        at io.quarkus.deployment.ExtensionLoader$3.execute(ExtensionLoader.java:858)
        at io.quarkus.builder.BuildContext.run(BuildContext.java:282)
        at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
        at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2513)
        at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1538)
        at java.base/java.lang.Thread.run(Thread.java:1589)
        at org.jboss.threads.JBossThread.run(JBossThread.java:501)
Caused by: jakarta.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type com.test.MyBean and qualifiers [@Default]
        - java member: com.test.qk.MainBean#bm
        - declared on CLASS bean [types=[com.test.qk.MainBean, java.lang.Object], qualifiers=[@Default, @Any], target=com.test.qk.MainBean]
        at io.quarkus.arc.processor.Beans.resolveInjectionPoint(Beans.java:477)
        at io.quarkus.arc.processor.BeanInfo.init(BeanInfo.java:624)
        at io.quarkus.arc.processor.BeanDeployment.init(BeanDeployment.java:299)
        ... 11 more

Expected behavior

Just like using the java -jar command as mentioned..

Actual behavior

jakarta.enterprise.inject.UnsatisfiedResolutionException

How to Reproduce?

use gradle (8.0 in my case) and kotlin ( in build.gradle.kts is this kotlin("jvm") version "1.9.10"), but gradlew --versions reports 1.8.10, probaby they are used for different purposes
using jdk 19
using quarkus 3.3.2

build project with just one bean producing a jar
second project has a @Startup bean that injects the bean from the first project
build it
run ./gradlew quarkusDev
It won't inject it..

Output of uname -a or ver

Linux verliba-lightpaint 6.2.0-31-generic #31~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Wed Aug 16 13:45:26 UTC 2 x86_64 x86_64 x86_64 GNU/Linux

Output of java -version

openjdk version "19.0.2" 2023-01-17 OpenJDK Runtime Environment (build 19.0.2+7-Ubuntu-0ubuntu322.04) OpenJDK 64-Bit Server VM (build 19.0.2+7-Ubuntu-0ubuntu322.04, mixed mode, sharing)

GraalVM version (if different from Java)

No response

Quarkus version or git rev

3.3.2

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

./gradlew --version ------------------------------------------------------------ Gradle 8.0 ------------------------------------------------------------ Build time: 2023-02-13 13:15:21 UTC Revision: 62ab9b7c7f884426cf79fbedcf07658b2dbe9e97 Kotlin: 1.8.10 Groovy: 3.0.13 Ant: Apache Ant(TM) version 1.10.11 compiled on July 10 2021 JVM: 19.0.2 (Private Build 19.0.2+7-Ubuntu-0ubuntu322.04) OS: Linux 6.2.0-31-generic amd64

Additional information

I can provide the ready made minimal project, that does this

@verliba verliba added the kind/bug Something isn't working label Sep 12, 2023
@quarkus-bot
Copy link

quarkus-bot bot commented Sep 12, 2023

/cc @evanchooly (kotlin), @geoand (kotlin), @glefloch, @quarkusio/devtools

@geoand
Copy link
Contributor

geoand commented Sep 12, 2023

Has the external jar been indexed as mentioned here?

@geoand geoand added the triage/needs-feedback We are waiting for feedback. label Sep 12, 2023
@verliba
Copy link
Author

verliba commented Sep 12, 2023

tst.zip
It has been indexed, it work in prod mode as expected..
Attached project reproduces the issue
You can run
./gradlew clean build quarkusDev in it
thanks

@geoand geoand removed the triage/needs-feedback We are waiting for feedback. label Sep 12, 2023
@verliba
Copy link
Author

verliba commented Sep 14, 2023

I found out, that making similar bean in java (not kotlin), is a temporary workaround, the bean is found, and used as expected

@DomenicDev
Copy link

I have the same issue in my multi-module project. Kotlin beans are not found, but Java beans are found in the (indexed) external module.

@gsmet
Copy link
Member

gsmet commented Aug 19, 2024

@Ladicek I'm pretty sure it's not related to Jandex or ArC but I wonder if you could have a look to determine what's going on here.

@Ladicek
Copy link
Contributor

Ladicek commented Sep 2, 2024

I'll take a look.

@Ladicek
Copy link
Contributor

Ladicek commented Sep 3, 2024

OK, so the issue here indeed is not related to ArC or Jandex. The problem is that during ApplicationArchiveBuildStep.addMarkerFilePaths(), the QuarkusClassLoader in TCCL (which is the "Deployment Class Loader: DEV") has the following normalPriorityElements:

  • MemoryClassPathElement
  • PathTreeClassPathElement for /home/lthon/tmp/tst/quarkus_tst/build/classes/kotlin/main
  • PathTreeClassPathElement for /home/lthon/tmp/tst/quarkus_tst/build/resources/main
  • PathTreeClassPathElement for /home/lthon/tmp/tst/bean_lib/build/resources/main

But there's nothing for /home/lthon/tmp/tst/bean_lib/build/classes/kotlin/main (neither in the TCCL, not in its parent, the "Augmentation Class Loader: DEV").

I tried debugging the GradleApplicationModelBuilder, but that's honestly a totally alien codebase to me and I couldn't make sense of it.

Speculation: it is entirely possible that this is just a part of the problem and there's more to it. ApplicationArchiveBuildStep.addMarkerFilePaths() asks the QuarkusClassLoader for ClassPathElements that contain the given marker file (META-INF/beans.xml in this case). That ends up returning the PathTreeClassPathElement for /home/lthon/tmp/tst/bean_lib/build/resources/main, which doesn't contain any .class files (which is correct), so the index ends up empty. Even if the QuarkusClassLoader had another entry for /home/lthon/tmp/tst/bean_lib/build/classes/kotlin/main, those .class files wouldn't be found.

I didn't look at how the ApplicationModel looks like for a Maven project, but it seems to me that there's just one ClassPathElement for each module, containing both .class files and resources. But, again, that's just speculation. The primary problem is that the GradleApplicationModelBuilder doesn't build the application model correctly.

(An ApplicationModel is turned into a "Deployment CL" in CuratedApplication.createDeploymentClassLoader().)

@gsmet
Copy link
Member

gsmet commented Sep 4, 2024

Hmmm, I wonder if I fixed it here: #42913 .

Because in retrospect, it looks a lot like the issue in #42860

@Ladicek
Copy link
Contributor

Ladicek commented Sep 4, 2024

I'm fairly sure the reproducer failed on 999-SNAPSHOT from yesterday, which would include the fix, but I'll retry just to be sure.

@gsmet
Copy link
Member

gsmet commented Sep 4, 2024

Ah bummer.

@gsmet
Copy link
Member

gsmet commented Sep 4, 2024

Maybe wait for 3.14.2 to land to be extra sure. I had some weird refresh issues with Gradle a few times.

@Ladicek
Copy link
Contributor

Ladicek commented Sep 4, 2024

Gotcha. I'll try with 999-SNAPSHOT now and with 3.14.2 once that is out.

@Ladicek
Copy link
Contributor

Ladicek commented Sep 4, 2024

Yeah, so I'm afraid it still fails on current 999-SNAPSHOT (where current means git ref 116c8a3062e7e80f5cacb7cc1261c2b8630366d2).

@gsmet
Copy link
Member

gsmet commented Sep 4, 2024

OK, I tried :]

@gsmet
Copy link
Member

gsmet commented Nov 22, 2024

I had another look. From my debugging session, it seems we don't have the lib around in the application model and I'm not really sure how we end up with the resources in the ClassLoader.

I'm not sure we are supporting whatever Gradle does with this:

includeBuild("../bean_lib")

I added an updated reproducer pointing to 999-SNAPSHOT:

gradle-includebuild-issue.zip

@cdsap if you have an idea what we are doing wrong, I'm all ears.

FWIW, the projects are Kotlin only and I know we had a few issues around that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants