You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Describe the bug
When an application relies on Gradle to compile code implemented in both Kotlin and Java, then any Quarkus test (@QuarkusTest) will ignore annotations on classes implemented in Java.
Only ./gradlew test with @QuarkusTest is affected:
./gradlew quarkusDev works perfectly
Maven works perfectly too, be it with ./mvnw test or ./mvnw initialize quarkus:dev.
Expected behavior
I expected annotations on Java classes to be detected.
Actual behavior
Annotations on Java classes are ignored. For example, a bean annotated with @ApplicationScoped will be ignored and attempting to inject it will fail:
javax.enterprise.inject.spi.DeploymentException: javax.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type io.quarkus.bugs.java.JavaComponent and qualifiers [@Default]
- java member: io.quarkus.bugs.KotlinService#javaComponent
- declared on CLASS bean [types=[io.quarkus.bugs.KotlinService, java.lang.Object], qualifiers=[@Default, @Any], target=io.quarkus.bugs.KotlinService]
javax.enterprise.inject.spi.DeploymentException: javax.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type io.quarkus.bugs.java.JavaComponent and qualifiers [@Default]
- java member: io.quarkus.bugs.KotlinService#javaComponent
- declared on CLASS bean [types=[io.quarkus.bugs.KotlinService, java.lang.Object], qualifiers=[@Default, @Any], target=io.quarkus.bugs.KotlinService]
Run ./gradlew quarkus:dev, then curl http://0.0.0.0:8080/hello: it works.
hello from JavaComponent
See the branch maven on the same repository for a proof that it works with Maven.
Run mvn initialize quarkus:dev (initialize is necessary to add another source directory), then curl http://0.0.0.0:8080/hello: it works.
hello from JavaComponent
Run mvn clean test: it works.
[INFO] BUILD SUCCESS
Configuration
N/A
Environment (please complete the following information):
Output of uname -a or ver: Linux yrodiere.redhat 5.8.17-200.fc32.x86_64 #1 SMP Thu Oct 29 18:14:53 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
Output of java -version:
openjdk version "11.0.9" 2020-10-20
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.9+11)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.9+11, mixed mode)
GraalVM version (if different from Java): N/A
Quarkus version or git rev: 1.9.2
Build tool (ie. output of mvnw --version or gradlew --version):
Additional context
I believe the culprit is in how QuarkusTestExtension infers the location of classes. What it does:
Take the test class, retrieve its location (io.quarkus.test.common.PathTestHelper#getTestClassesLocation)
Use a hardcoded map to infer the location of main classes (io.quarkus.test.common.PathTestHelper#getAppClassLocationForTestLocation).
But in the case of Gradle with Kotlinand Java code, the source code is in two different directories (src/main/kotlin and src/main/java), and the compiled classes as well (build/classes/java and build/classes/kotlin). QuarkusTestExtension only uses build/classes/kotlin, which explains the problem.
Regarding the use case, it may seem exotic, but for Kotlin, I don't think it is:
That the main annotation processor for Kotlin (kapt) produces Java code by default. So if you write only Kotlin code in a Quarkus application, and you need to generate beans or otherwise annotated classes through an annotation processor, you will be affected.
Even if you don't use annotation processors, Java interop, and the ability to mix Java and Kotlin code in the same project, is apparently an important feature of Kotlin.
On example of annotation processors that produce CDI beans: MapStruct, frequently used to map between DTO and entities. It generates "mapper" classes that can be injected using CDI.
The text was updated successfully, but these errors were encountered:
Thanks for reporting this @yrodiere. You are right, as maven output all classes into the target/classes directory, there is no problem.
I have a working fix for gradle. I just need to add a test.
Describe the bug
When an application relies on Gradle to compile code implemented in both Kotlin and Java, then any Quarkus test (
@QuarkusTest
) will ignore annotations on classes implemented in Java.Only
./gradlew test
with@QuarkusTest
is affected:./gradlew quarkusDev
works perfectly./mvnw test
or./mvnw initialize quarkus:dev
.Expected behavior
I expected annotations on Java classes to be detected.
Actual behavior
Annotations on Java classes are ignored. For example, a bean annotated with
@ApplicationScoped
will be ignored and attempting to inject it will fail:To Reproduce
Reproducer with Gradle: https://github.com/yrodiere/quarkus-bug-mixed-kotlin-java
Run
./gradlew clean test
: it fails.Run
./gradlew quarkus:dev
, thencurl http://0.0.0.0:8080/hello
: it works.See the branch
maven
on the same repository for a proof that it works with Maven.Run
mvn initialize quarkus:dev
(initialize
is necessary to add another source directory), thencurl http://0.0.0.0:8080/hello
: it works.Run
mvn clean test
: it works.Configuration
N/A
Environment (please complete the following information):
uname -a
orver
:Linux yrodiere.redhat 5.8.17-200.fc32.x86_64 #1 SMP Thu Oct 29 18:14:53 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
java -version
:mvnw --version
orgradlew --version
):Additional context
I believe the culprit is in how
QuarkusTestExtension
infers the location of classes. What it does:io.quarkus.test.common.PathTestHelper#getTestClassesLocation
)io.quarkus.test.common.PathTestHelper#getAppClassLocationForTestLocation
).But in the case of Gradle with Kotlinand Java code, the source code is in two different directories (
src/main/kotlin
andsrc/main/java
), and the compiled classes as well (build/classes/java
andbuild/classes/kotlin
).QuarkusTestExtension
only usesbuild/classes/kotlin
, which explains the problem.Regarding the use case, it may seem exotic, but for Kotlin, I don't think it is:
On example of annotation processors that produce CDI beans: MapStruct, frequently used to map between DTO and entities. It generates "mapper" classes that can be injected using CDI.
The text was updated successfully, but these errors were encountered: