micronaut-projects / micronaut-discovery-client

Micronaut's Discovery Client
Apache License 2.0
22 stars 20 forks source link

VaultConfigurationClient failed if 1 path is not found #465

Closed FrogDevelopper closed 1 year ago

FrogDevelopper commented 1 year ago

Expected Behavior

If a path return 404 - NOT_FOUND, the application start

Actual Behaviour

The API return 404 - NOT_FOUND with a body

{
    "errors": []
}

and the application does not start and we got the error:

java.lang.IllegalAccessError: class io.micronaut.http.hateoas.JsonError$Creator4JacksonDeserializer066f2705 tried to access method 'void io.micronaut.http.hateoas.JsonError.()' (io.micronaut.http.hateoas.JsonError$Creator4JacksonDeserializer066f2705 is in unnamed module of loader com.fasterxml.jackson.module.afterburner.util.MyClassLoader @7e93f3b0; io.micronaut.http.hateoas.JsonError is in unnamed module of loader 'app') at io.micronaut.http.hateoas.JsonError$Creator4JacksonDeserializer066f2705.createUsingDefault(io/micronaut/http/hateoas/JsonError$Creator4JacksonDeserializer.java) at com.fasterxml.jackson.module.afterburner.deser.SuperSonicBeanDeserializer.deserialize(SuperSonicBeanDeserializer.java:136) at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:323) at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4730) at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3771) at io.micronaut.jackson.databind.JacksonDatabindMapper.readValue(JacksonDatabindMapper.java:119) at io.micronaut.json.codec.MapperMediaTypeCodec.decode(MapperMediaTypeCodec.java:190) at io.micronaut.http.client.netty.FullNettyClientHttpResponse.convertByteBuf(FullNettyClientHttpResponse.java:279) at io.micronaut.http.client.netty.FullNettyClientHttpResponse.lambda$getBody$1(FullNettyClientHttpResponse.java:217) at java.base/java.util.HashMap.computeIfAbsent(HashMap.java:1220) at io.micronaut.http.client.netty.FullNettyClientHttpResponse.getBody(FullNettyClientHttpResponse.java:191) at io.micronaut.http.client.exceptions.HttpClientResponseException.initResponse(HttpClientResponseException.java:95) at io.micronaut.http.client.exceptions.HttpClientResponseException.(HttpClientResponseException.java:63) at io.micronaut.http.client.exceptions.HttpClientResponseException.(HttpClientResponseException.java:50) at io.micronaut.http.client.exceptions.HttpClientResponseException.(HttpClientResponseException.java:41) at io.micronaut.http.client.netty.DefaultHttpClient$FullHttpResponseHandler.makeErrorFromRequestBody(DefaultHttpClient.java:2232) at io.micronaut.http.client.netty.DefaultHttpClient$FullHttpResponseHandler.buildResponse(DefaultHttpClient.java:2194) at io.micronaut.http.client.netty.DefaultHttpClient$FullHttpResponseHandler.buildResponse(DefaultHttpClient.java:2117) at io.micronaut.http.client.netty.DefaultHttpClient$BaseHttpResponseHandler.channelReadInstrumented(DefaultHttpClient.java:2092) at io.micronaut.http.client.netty.DefaultHttpClient$FullHttpResponseHandler.channelReadInstrumented(DefaultHttpClient.java:2153) at io.micronaut.http.client.netty.DefaultHttpClient$FullHttpResponseHandler.channelReadInstrumented(DefaultHttpClient.java:2117) at io.micronaut.http.client.netty.SimpleChannelInboundHandlerInstrumented.channelRead0(SimpleChannelInboundHandlerInstrumented.java:49)

If I understand it correctly, as the body returned by the response is not taken into account, the response generated has a null body, so the serializer try to use the empty constructor of JsonError which is package accessible only

    @Internal
    JsonError() {
    }

so can not be accessed by the Jackson and thus throw the error

I was able to pass through this issue by replacing client VaultConfigHttpClientV2 by a custom one, adding the errorType parameter to the client configuration

@Client(
     value = VaultClientConfiguration.VAULT_CLIENT_CONFIG_ENDPOINT, 
     configuration = VaultClientConfiguration.class, 
     errorType = VaultErrorV2.class)
@Replaces(io.micronaut.discovery.vault.config.v2.VaultConfigHttpClientV2.class)
@BootstrapContextCompatible
public interface VaultConfigHttpClientV2Fixed extends VaultConfigHttpClient<VaultResponseV2> {
...
}
@Introspected
public class VaultErrorV2 {

    protected List<String> errors;

    @JsonCreator
    @Internal
    public VaultErrorV2(@JsonProperty("errors") final List<String> errors) {
        this.errors = errors;
    }

    public List<String> getErrors() {
        return errors;
    }
}

Steps To Reproduce

I'll try to create a small project to reproduce it

Environment Information

Example Application

No response

Version

3.9.1

FrogDevelopper commented 1 year ago

Well, by creating a minimum application to reproduce it I found the culprit, as I wasn't able to reproduce it. So, by excluding the "jackson-module-afterburner, I don't have the issue anymore

exclude(group = "com.fasterxml.jackson.module", module = "jackson-module-afterburner")