quarkus: @RunOnVirtualThread cannot be used in override methods
Describe the bug
Inside a Quarkus 3.4.1 application, I cannot log virtual threads to verify virtual threads usage for a simple demo, using @RunOnVirtualThread.
I am running the app with /Library/Java/JavaVirtualMachines/corretto-19.0.2/Contents/Home/bin/java (Java 19)
Inside maven-compiler-plugin I have this configuration
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${compiler-plugin.version}</version>
<configuration>
<compilerArgs>
<arg>--enable-preview</arg>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
Like said inside https://quarkus.io/guides/virtual-threads#terminology guide.
I have
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-reactive-jackson</artifactId>
</dependency>
These log properties
# Log
quarkus.log.console.format=%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c{2.}] %h %H ${quarkus.http.port} %i (%t) %s%e%n
quarkus.log.console.level=INFO
quarkus.log.file.enable=false
#quarkus.log.file.path=/tmp/bile.log
quarkus.log.file.format=%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c{2.}] %h %H ${quarkus.http.port} %i (%t) %s%e%n
With this configuration I would like to log if a method is running with virtual threads with quarkus-virtual-thread- prefix, but when I run a REST call to method annotated with @RunOnVirtualThread, it doesn’t log virtual threads. The method is
@Override
@RunOnVirtualThread
public Response reactive() {
log.info("operationName=reactive");
// Runs on the event loop
return Response.ok(Map.of("msg", Thread.currentThread())).build();
}
How can I verify that actual virtual threads is running?
Expected behavior
I’m expecting like this
2023-09-25 22:48:13,539 INFO [it.gd.bo.MyApiImpl] lorenzos-macbook-pro lorenzos-macbook-pro.local 8083 15051 (executor-quarkus-virtual-thread-5) operationName=reactive
or something like this to verify actual virtual threads instead platform threads
Actual behavior
Actual log is
2023-09-25 22:48:13,539 INFO [it.gd.bo.MyApiImpl] lorenzos-macbook-pro lorenzos-macbook-pro.local 8083 15051 (executor-thread-5) operationName=reactive
How to Reproduce?
No response
Output of uname -a or ver
Darwin Lorenzos-MacBook-Pro.local 22.3.0 Darwin Kernel Version 22.3.0: Mon Jan 30 20:39:46 PST 2023; root:xnu-8792.81.3~2/RELEASE_ARM64_T6020 arm64
Output of java -version
java 19
GraalVM version (if different from Java)
No response
Quarkus version or git rev
3.4.1
Build tool (ie. output of mvnw --version or gradlew --version)
No response
Additional information
My laptop is MacOs with ARM architecture:
Darwin Lorenzos-MacBook-Pro.local 22.3.0 Darwin Kernel Version 22.3.0: Mon Jan 30 20:39:46 PST 2023; root:xnu-8792.81.3~2/RELEASE_ARM64_T6020 arm64
Configuration of app
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>it.gdgpt</groupId>
<artifactId>virtual-kafka-streams</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<compiler-plugin.version>3.10.1</compiler-plugin.version>
<maven.compiler.source>19</maven.compiler.source>
<maven.compiler.target>19</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
<quarkus.platform.group-id>io.quarkus.platform</quarkus.platform.group-id>
<quarkus.platform.version>3.4.1</quarkus.platform.version>
<skipITs>true</skipITs>
<surefire-plugin.version>3.0.0-M7</surefire-plugin.version>
<npg-be-ark-library.version>0.0.2-java-1.8-SNAPSHOT</npg-be-ark-library.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>${quarkus.platform.group-id}</groupId>
<artifactId>${quarkus.platform.artifact-id}</artifactId>
<version>${quarkus.platform.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<modules>
<module>virtual-kafka-streams-liquibase</module>
<module>virtual-kafka-streams-application</module>
</modules>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>it.gdgpt</groupId>
<artifactId>virtual-kafka-streams</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>virtual-kafka-streams-application</artifactId>
<version>1.0.0-SNAPSHOT</version>
<dependencies>
<!-- <dependency>-->
<!-- <groupId>io.quarkus</groupId>-->
<!-- <artifactId>quarkus-smallrye-reactive-messaging-kafka</artifactId>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>io.quarkus</groupId>-->
<!-- <artifactId>quarkus-kafka-streams</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>io.vavr</groupId>
<artifactId>vavr</artifactId>
<version>0.10.4</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-orm</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-rest-client-reactive</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-openapi</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-quartz</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-scheduler</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>io.quarkus</groupId>-->
<!-- <artifactId>quarkus-resteasy-jackson</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-reactive-jackson</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-health</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-postgresql</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-h2</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-arc</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>io.quarkus</groupId>-->
<!-- <artifactId>quarkus-resteasy</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>${quarkus.platform.group-id}</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>${quarkus.platform.version}</version>
<extensions>true</extensions>
<executions>
<execution>
<goals>
<goal>build</goal>
<goal>generate-code</goal>
<goal>generate-code-tests</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${compiler-plugin.version}</version>
<configuration>
<compilerArgs>
<arg>--enable-preview</arg>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<configuration>
<systemPropertyVariables>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
<maven.home>${maven.home}</maven.home>
</systemPropertyVariables>
</configuration>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<systemPropertyVariables>
<native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
<maven.home>${maven.home}</maven.home>
</systemPropertyVariables>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>19</source>
<target>19</target>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>native</id>
<activation>
<property>
<name>native</name>
</property>
</activation>
<properties>
<skipITs>false</skipITs>
<quarkus.package.type>native</quarkus.package.type>
</properties>
</profile>
</profiles>
</project>
About this issue
- Original URL
- State: open
- Created 9 months ago
- Comments: 15 (11 by maintainers)
A possible workaround is given by the following statement from the Jakarta REST specification:
You can just copy the JAX-RS annotations from the interface to the resource method and then add
@RunOnVirtualThread.@Ladicek I’m going to test this workaround, thanks!
How annotation inheritance in Java works is described here: https://docs.oracle.com/javase/8/docs/api/java/lang/annotation/Inherited.html Notably, annotations are only inherited on classes (not on fields or methods), and only from superclasses (not from interfaces).
How annotation inheritance in JAX-RS works is described here: https://jakarta.ee/specifications/restful-ws/3.1/jakarta-restful-ws-spec-3.1#annotationinheritance Notably, it only concerns inheritance of JAX-RS annotations on methods and method parameters. The way I read it, it means that non-JAX-RS annotations are never inherited and should be present on the resource method.
So if I understand the present issue correctly, we have a resource class with a resource method that inherits JAX-RS annotations from an interface method and then adds
@RunOnVirtualThreadon its own. I think it’s fairly sensible to treat some of our annotations as JAX-RS annotations, but I don’t feel like@RunOnVirtualThreadshould be one of those. It’s not my call to make, but if you agree with my opinion, what we have here is a genuine bug.