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

Resteasy Reactive: Fix native mode when using Files #26002

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import java.util.List;
import java.util.Map;
import java.util.function.Predicate;

import javax.ws.rs.core.MediaType;

Expand All @@ -23,9 +22,7 @@

import io.quarkus.deployment.Capabilities;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.builditem.BytecodeTransformerBuildItem;
import io.quarkus.deployment.builditem.GeneratedClassBuildItem;
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
import io.quarkus.resteasy.reactive.common.deployment.JsonDefaultProducersHandler;
import io.quarkus.resteasy.reactive.server.runtime.ResteasyReactiveRecorder;

Expand All @@ -36,22 +33,15 @@ public class QuarkusServerEndpointIndexer

private final Capabilities capabilities;
private final BuildProducer<GeneratedClassBuildItem> generatedClassBuildItemBuildProducer;
private final BuildProducer<BytecodeTransformerBuildItem> bytecodeTransformerBuildProducer;
private final BuildProducer<ReflectiveClassBuildItem> reflectiveClassProducer;
private final DefaultProducesHandler defaultProducesHandler;
private final JsonDefaultProducersHandler jsonDefaultProducersHandler;
private final ResteasyReactiveRecorder resteasyReactiveRecorder;

private final Predicate<String> applicationClassPredicate;

QuarkusServerEndpointIndexer(Builder builder) {
super(builder);
this.capabilities = builder.capabilities;
this.generatedClassBuildItemBuildProducer = builder.generatedClassBuildItemBuildProducer;
this.bytecodeTransformerBuildProducer = builder.bytecodeTransformerBuildProducer;
this.reflectiveClassProducer = builder.reflectiveClassProducer;
this.defaultProducesHandler = builder.defaultProducesHandler;
this.applicationClassPredicate = builder.applicationClassPredicate;
this.resteasyReactiveRecorder = builder.resteasyReactiveRecorder;
this.jsonDefaultProducersHandler = new JsonDefaultProducersHandler();
}
Expand Down Expand Up @@ -109,11 +99,8 @@ public static final class Builder extends AbstractBuilder<Builder> {
private final Capabilities capabilities;

private BuildProducer<GeneratedClassBuildItem> generatedClassBuildItemBuildProducer;
private BuildProducer<BytecodeTransformerBuildItem> bytecodeTransformerBuildProducer;
private BuildProducer<ReflectiveClassBuildItem> reflectiveClassProducer;
private ResteasyReactiveRecorder resteasyReactiveRecorder;
private DefaultProducesHandler defaultProducesHandler = DefaultProducesHandler.Noop.INSTANCE;
public Predicate<String> applicationClassPredicate;

public Builder(Capabilities capabilities) {
this.capabilities = capabilities;
Expand All @@ -124,29 +111,12 @@ public QuarkusServerEndpointIndexer build() {
return new QuarkusServerEndpointIndexer(this);
}

public Builder setBytecodeTransformerBuildProducer(
BuildProducer<BytecodeTransformerBuildItem> bytecodeTransformerBuildProducer) {
this.bytecodeTransformerBuildProducer = bytecodeTransformerBuildProducer;
return this;
}

public Builder setGeneratedClassBuildItemBuildProducer(
BuildProducer<GeneratedClassBuildItem> generatedClassBuildItemBuildProducer) {
this.generatedClassBuildItemBuildProducer = generatedClassBuildItemBuildProducer;
return this;
}

public Builder setReflectiveClassProducer(
BuildProducer<ReflectiveClassBuildItem> reflectiveClassProducer) {
this.reflectiveClassProducer = reflectiveClassProducer;
return this;
}

public Builder setApplicationClassPredicate(Predicate<String> applicationClassPredicate) {
this.applicationClassPredicate = applicationClassPredicate;
return this;
}

public Builder setResteasyReactiveRecorder(ResteasyReactiveRecorder resteasyReactiveRecorder) {
this.resteasyReactiveRecorder = resteasyReactiveRecorder;
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,6 @@ public void setupEndpoints(ApplicationIndexBuildItem applicationIndexBuildItem,
Optional<ResourceScanningResultBuildItem> resourceScanningResultBuildItem,
BuildProducer<GeneratedClassBuildItem> generatedClassBuildItemBuildProducer,
BuildProducer<BytecodeTransformerBuildItem> bytecodeTransformerBuildItemBuildProducer,
BuildProducer<ReflectiveClassBuildItem> reflectiveClassBuildItemBuildProducer,
ResteasyReactiveRecorder recorder,
List<ServerDefaultProducesHandlerBuildItem> serverDefaultProducesHandlers,
Optional<ClassLevelExceptionMappersBuildItem> classLevelExceptionMappers,
Expand Down Expand Up @@ -424,8 +423,6 @@ public void setupEndpoints(ApplicationIndexBuildItem applicationIndexBuildItem,
.setEndpointInvokerFactory(
new QuarkusInvokerFactory(generatedClassBuildItemBuildProducer, recorder))
.setGeneratedClassBuildItemBuildProducer(generatedClassBuildItemBuildProducer)
.setBytecodeTransformerBuildProducer(bytecodeTransformerBuildItemBuildProducer)
.setReflectiveClassProducer(reflectiveClassBuildItemBuildProducer)
.setExistingConverters(existingConverters)
.setScannedResourcePaths(scannedResourcePaths)
.setConfig(createRestReactiveConfig(config))
Expand Down Expand Up @@ -517,7 +514,6 @@ private boolean hasAnnotation(MethodInfo method, short paramPosition, DotName an
}
})
.setResteasyReactiveRecorder(recorder)
.setApplicationClassPredicate(applicationClassPredicate)
.setTargetJavaVersion(new TargetJavaVersion() {

private final Status result;
Expand Down Expand Up @@ -558,23 +554,27 @@ public Status isJava19OrHigher() {
}

serverEndpointIndexerBuilder.setMultipartReturnTypeIndexerExtension(new QuarkusMultipartReturnTypeHandler(
generatedClassBuildItemBuildProducer, applicationClassPredicate, reflectiveClassBuildItemBuildProducer));
generatedClassBuildItemBuildProducer, applicationClassPredicate, reflectiveClass));
serverEndpointIndexerBuilder.setMultipartParameterIndexerExtension(new QuarkusMultipartParamHandler(
generatedClassBuildItemBuildProducer, applicationClassPredicate, reflectiveClassBuildItemBuildProducer,
generatedClassBuildItemBuildProducer, applicationClassPredicate, reflectiveClass,
bytecodeTransformerBuildItemBuildProducer));
serverEndpointIndexer = serverEndpointIndexerBuilder.build();

Map<String, List<EndpointConfig>> allMethods = new HashMap<>();
for (ClassInfo i : scannedResources.values()) {
Optional<ResourceClass> endpoints = serverEndpointIndexer.createEndpoints(i, true);
if (endpoints.isPresent()) {
ResourceClass resourceClass = endpoints.get();
if (singletonClasses.contains(i.name().toString())) {
endpoints.get().setFactory(new SingletonBeanFactory<>(i.name().toString()));
resourceClass.setFactory(new SingletonBeanFactory<>(i.name().toString()));
}
resourceClasses.add(endpoints.get());
for (ResourceMethod rm : endpoints.get().getMethods()) {
addResourceMethodByPath(allMethods, endpoints.get().getPath(), i, rm);
resourceClasses.add(resourceClass);
for (ResourceMethod rm : resourceClass.getMethods()) {
addResourceMethodByPath(allMethods, resourceClass.getPath(), i, rm);
}

// Ensure native support of resource endpoints:
reflectiveClass.produce(new ReflectiveClassBuildItem(false, true, false, resourceClass.getClassName()));
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@geoand this is the fix I added to solve the linked issue. However, as it works when the resource is not using a File class, I doubt this is the right fix... tho I could not find the right path.

Copy link
Contributor

Choose a reason for hiding this comment

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

Indeed, this is not the fix we want to apply. I will have a closer look later

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I converted this pull request in draft, just to reuse the tests and the clean up.

}
}

Expand Down
26 changes: 26 additions & 0 deletions integration-tests/rest-client-reactive/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
<artifactId>quarkus-integration-test-rest-client-reactive</artifactId>
<name>Quarkus - Integration Tests - REST Client Reactive</name>

<properties>
<integration.tests.invoker.properties>invoker.jvm.properties</integration.tests.invoker.properties>
</properties>

<!--todo add ssl tests-->

<dependencies>
Expand Down Expand Up @@ -160,6 +164,27 @@
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-invoker-plugin</artifactId>
<executions>
<execution>
<id>integration-tests</id>
<goals>
<goal>run</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
<configuration>
<cloneProjectsTo>${project.build.directory}/it</cloneProjectsTo>
<cloneClean>true</cloneClean>
<preBuildHookScript>setup</preBuildHookScript>
<postBuildHookScript>verify</postBuildHookScript>
<addTestClassPath>true</addTestClassPath>
<streamLogs>true</streamLogs>
<invokerPropertiesFile>${integration.tests.invoker.properties}</invokerPropertiesFile>
</configuration>
</plugin>
</plugins>
</build>

Expand All @@ -173,6 +198,7 @@
</activation>
<properties>
<quarkus.package.type>native</quarkus.package.type>
<integration.tests.invoker.properties>invoker.native.properties</integration.tests.invoker.properties>
</properties>
<!-- add some custom config, the rest comes from parent -->
<build>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
invoker.goals=clean verify
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
invoker.goals=clean verify -Dnative
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.acme</groupId>
<artifactId>getting-started-from-guide</artifactId>
<version>0.1-SNAPSHOT</version>
<properties>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<surefire-plugin.version>3.0.0-M5</surefire-plugin.version>
<maven.compiler.source>11</maven.compiler.source>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-bom</artifactId>
<version>@project.version@</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-reactive-jackson</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-rest-client-reactive-jackson</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>io.quarkus</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>@project.version@</version>
<executions>
<execution>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
</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>
</plugins>
</build>
<profiles>
<profile>
<id>native</id>
<activation>
<property>
<name>native</name>
</property>
</activation>
<properties>
<quarkus.package.type>native</quarkus.package.type>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>${native.surefire.skip}</skipTests>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.acme.rest.client;

import java.util.List;

public class Extension {
public String id;
public String name;
public String shortName;
public List<String> keywords;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package org.acme.rest.client;

import io.smallrye.common.annotation.Blocking;
import org.eclipse.microprofile.rest.client.inject.RestClient;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.POST;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Set;

@Path("/extension")
public class ExtensionsResource {

@RestClient
ExtensionsService extensionsService;

@GET
@Path("/id/{id}")
@Blocking
public Set<Extension> id(String id) {
return extensionsService.getById(id);
}

@POST
@Path("/init")
public void initialize() throws IOException {
extensionsService.registerFile(Files.createTempFile("any", ".txt").toFile());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package org.acme.rest.client;

import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.POST;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import java.io.File;
import java.util.Set;

@Path("/extensions")
@RegisterRestClient
public interface ExtensionsService {

@GET
Set<Extension> getById(@QueryParam("id") String id);

@POST
@Consumes(MediaType.APPLICATION_OCTET_STREAM)
String registerFile(File file);
}