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

Consider build time conditions when determining the JAX-RS Application class #23402

Merged
merged 1 commit into from
Feb 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ void deprioritizeLegacyProviders(BuildProducer<MessageBodyReaderOverrideBuildIte
* @param buildTimeConditions the build time conditions from which the excluded classes are extracted.
* @return the set of classes that have been annotated with unsuccessful build time conditions.
*/
private static Set<String> getExcludedClasses(List<BuildTimeConditionBuildItem> buildTimeConditions) {
public static Set<String> getExcludedClasses(List<BuildTimeConditionBuildItem> buildTimeConditions) {
return buildTimeConditions.stream()
.filter(item -> !item.isEnabled())
.map(BuildTimeConditionBuildItem::getTarget)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -756,7 +756,7 @@ public void setupDeployment(BeanArchiveIndexBuildItem beanArchiveIndexBuildItem,
BeanFactory<ResteasyReactiveInitialiser> initClassFactory = recorder.factory(QUARKUS_INIT_CLASS,
beanContainerBuildItem.getValue());

String applicationPath = determineApplicationPath(index, getAppPath(serverConfig.path));
String applicationPath = determineApplicationPath(appResult, getAppPath(serverConfig.path));
// spec allows the path contain encoded characters
if ((applicationPath != null) && applicationPath.contains("%")) {
applicationPath = Encode.decodePath(applicationPath);
Expand Down Expand Up @@ -981,32 +981,19 @@ private Optional<String> getAppPath(Optional<String> newPropertyValue) {
return newPropertyValue;
}

private String determineApplicationPath(IndexView index, Optional<String> defaultPath) {
Collection<AnnotationInstance> applicationPaths = index.getAnnotations(ResteasyReactiveDotNames.APPLICATION_PATH);
if (applicationPaths.isEmpty()) {
private String determineApplicationPath(ApplicationScanningResult appResult,
Optional<String> defaultPath) {
if (appResult.getSelectedAppClass() == null) {
return defaultPath.orElse("/");
}
// currently we only examine the first class that is annotated with @ApplicationPath so best
// fail if the user code has multiple such annotations instead of surprising the user
// at runtime
if (applicationPaths.size() > 1) {
StringBuilder sb = new StringBuilder();
boolean first = true;
for (AnnotationInstance annotationInstance : applicationPaths) {
if (first) {
first = false;
} else {
sb.append(",");
}
sb.append(annotationInstance.target().asClass().name().toString());
}
throw new RuntimeException("Multiple classes ( " + sb.toString()
+ ") have been annotated with @ApplicationPath which is currently not supported");
AnnotationInstance applicationPathValue = appResult.getSelectedAppClass()
.classAnnotation(ResteasyReactiveDotNames.APPLICATION_PATH);
if (applicationPathValue == null) {
return defaultPath.orElse("/");
}
String applicationPath = null;
AnnotationValue applicationPathValue = applicationPaths.iterator().next().value();
if ((applicationPathValue != null)) {
applicationPath = applicationPathValue.asString();
if ((applicationPathValue.value() != null)) {
applicationPath = applicationPathValue.value().asString();
}
return applicationPath;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package io.quarkus.resteasy.reactive.server.test;

import static io.restassured.RestAssured.get;

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Application;

import org.hamcrest.Matchers;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.arc.properties.IfBuildProperty;
import io.quarkus.test.QuarkusUnitTest;

class MultipleApplicationClassesWithBuildProfileTest {

@RegisterExtension
static QuarkusUnitTest runner = new QuarkusUnitTest()
.withApplicationRoot((jar) -> jar
.addClasses(
Application1.class, Application2.class, TestResource.class));

@Test
public void testNoAnnotation() {
get("/1/test")
.then()
.statusCode(200)
.body(Matchers.equalTo("test"));
}

@ApplicationPath("1")
public static class Application1 extends Application {

}

@ApplicationPath("2")
@IfBuildProperty(name = "some.prop2", stringValue = "v2")
public static class Application2 extends Application {

}

@Path("test")
public static class TestResource {

@GET
public String get() {
return "test";
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ public static ApplicationScanningResult scanForApplicationClass(IndexView index,
if (Modifier.isAbstract(applicationClassInfo.flags())) {
continue;
}
if (excludedClasses.contains(applicationClassInfo.name().toString())) {
continue;
}
if (selectedAppClass != null) {
throw new RuntimeException("More than one Application class: " + applications);
}
Expand Down