Skip to content

Commit

Permalink
Allows users to exclude DefaultMismatchedInputException
Browse files Browse the repository at this point in the history
A few users have run into an issue where
they are trying to handle all Jackson exceptions
but the existence of DefaultMismatchedInputException
prevents that for MismatchedInputException
(as per JAX-RS / Jakarta REST rules).

This change allows users to do use:

quarkus.class-loading.removed-resources."io.quarkus\:quarkus-rest-jackson"=io/quarkus/resteasy/reactive/jackson/runtime/mappers/DefaultMismatchedInputException.class

in order to have Quarkus ignore the mapper.
  • Loading branch information
geoand committed Sep 10, 2024
1 parent 6748311 commit 7f09b8c
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@
import io.quarkus.resteasy.reactive.jackson.EnableSecureSerialization;
import io.quarkus.resteasy.reactive.jackson.SecureField;
import io.quarkus.resteasy.reactive.jackson.runtime.ResteasyReactiveServerJacksonRecorder;
import io.quarkus.resteasy.reactive.jackson.runtime.mappers.DefaultMismatchedInputException;
import io.quarkus.resteasy.reactive.jackson.runtime.mappers.NativeInvalidDefinitionExceptionMapper;
import io.quarkus.resteasy.reactive.jackson.runtime.security.RolesAllowedConfigExpStorage;
import io.quarkus.resteasy.reactive.jackson.runtime.security.SecurityCustomSerialization;
Expand Down Expand Up @@ -108,6 +107,7 @@ public class ResteasyReactiveJacksonProcessor {
private static final String[] EMPTY_STRING_ARRAY = new String[0];
private static final List<String> HANDLED_MEDIA_TYPES = List.of(MediaType.APPLICATION_JSON, APPLICATION_NDJSON,
APPLICATION_STREAM_JSON);
public static final String DEFAULT_MISMATCHED_INPUT_EXCEPTION = "io.quarkus.resteasy.reactive.jackson.runtime.mappers.DefaultMismatchedInputException";

@BuildStep
void feature(BuildProducer<FeatureBuildItem> feature) {
Expand All @@ -130,9 +130,16 @@ ReinitializeVertxJsonBuildItem vertxJson() {
}

@BuildStep
ExceptionMapperBuildItem exceptionMappers() {
return new ExceptionMapperBuildItem(DefaultMismatchedInputException.class.getName(),
MismatchedInputException.class.getName(), Priorities.USER + 100, false);
void exceptionMappers(BuildProducer<ExceptionMapperBuildItem> producer) {
try {
Thread.currentThread().getContextClassLoader().loadClass(DEFAULT_MISMATCHED_INPUT_EXCEPTION);
} catch (NoClassDefFoundError | ClassNotFoundException e) {
// the class is not available, likely due to quarkus.class-loading.removed-resources."io.quarkus\:quarkus-rest-jackson"=io/quarkus/resteasy/reactive/jackson/runtime/mappers/DefaultMismatchedInputException.class
return;
}

producer.produce(new ExceptionMapperBuildItem(DEFAULT_MISMATCHED_INPUT_EXCEPTION,
MismatchedInputException.class.getName(), Priorities.USER + 100, false));
}

@BuildStep
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package io.quarkus.resteasy.reactive.jackson.deployment.test;

import java.util.function.Supplier;

import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;

import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import com.fasterxml.jackson.databind.DatabindException;

import io.quarkus.test.QuarkusUnitTest;
import io.restassured.RestAssured;

public class ExceptionInReaderWithExcludedBuiltInAndIncludedCustomMapperTest {

@RegisterExtension
static QuarkusUnitTest test = new QuarkusUnitTest()
.setArchiveProducer(new Supplier<>() {
@Override
public JavaArchive get() {
return ShrinkWrap.create(JavaArchive.class)
.addClasses(FroMage.class, FroMageEndpoint.class, DatabindExceptionMapper.class);
}
}).overrideConfigKey("quarkus.class-loading.removed-resources.\"io.quarkus\\:quarkus-rest-jackson\"",
"io/quarkus/resteasy/reactive/jackson/runtime/mappers/DefaultMismatchedInputException.class");

@Test
public void test() {
RestAssured.with().contentType("application/json").body("{\"name\": \"brie\"}").put("/fromage")
.then().statusCode(999);
}

@Provider
public static class DatabindExceptionMapper implements ExceptionMapper<DatabindException> {

@Override
public Response toResponse(DatabindException exception) {
return Response.status(999).build();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import io.quarkus.runtime.LaunchMode;

@SuppressWarnings("unused")
public class DefaultMismatchedInputException
implements ExceptionMapper<com.fasterxml.jackson.databind.exc.MismatchedInputException> {

Expand Down

0 comments on commit 7f09b8c

Please sign in to comment.