micronaut-projects / micronaut-gradle-plugin

A Gradle Plugin for Micronaut
Apache License 2.0
67 stars 44 forks source link

Add a DSL element to specify the runtime serializer #592

Open melix opened 2 years ago

melix commented 2 years ago

Issue description

Builds migrating to Micronaut 4 will fail because, by default, no runtime serializer is present. For example using this simple build script:

plugins {
    id "io.micronaut.application"
}

micronaut {
    version "4.0.0-SNAPSHOT"
    runtime "netty"
    testRuntime "junit5"
}

repositories {
    mavenCentral()
}
mainClassName = "example.Application"

Running the app (or tests) will fail with:

Caused by: java.lang.NoClassDefFoundError at null:-1

Which is not extremely user-friendly.

Therefore, we need to add a new DSL option to select the serialization framework:

micronaut {
    version "4.0.0-SNAPSHOT"
    runtime "netty"
    serialzation "serde-jackson" // This is new
    testRuntime "junit5"
}

With currently 2 supported options:

There should also be a default value, which should probably be serde-jackson for 4.0.0.

Note that we may face the problem of the test resources client not working with serde (see https://github.com/micronaut-projects/micronaut-test-resources/issues/103)

melix commented 2 years ago

Another discussion point is whether this should also automatically add a dependency substitution rule (which would remove the need for having it in micronaut-starter). This would definitely require having a proper fix for the test resources client now, as there seem to have no way to figure out what is the current object mapper (/cc @graemerocher ).

graemerocher commented 2 years ago

You can obtain the current object mapper with JsonMapper.createDefault https://github.com/micronaut-projects/micronaut-core/blob/950ade6625291b10295be93fa72c1490378bf95f/json-core/src/main/java/io/micronaut/json/JsonMapper.java#L235

Test resources server could have a default dependency on Micronaut Serialization that implements this.

I am not sure the need for having another DSL element. Perhaps a better error message in core should be worked on instead.

melix commented 2 years ago

I am not sure the need for having another DSL element. Perhaps a better error message in core should be worked on instead.

I think we definitely need a better error message. As for having a DSL element, I think it aligns well with the rest of the DSL, especially if we combine it with a rule to automatically do substitutions.

You can obtain the current object mapper with JsonMapper.createDefault https://github.com/micronaut-projects/micronaut-core/blob/950ade6625291b10295be93fa72c1490378bf95f/json-core/src/main/java/io/micronaut/json/JsonMapper.java#L235

Right, so we can give it a try for a 2.0.0 release of test resources which requires Micronaut 4+.

Test resources server could have a default dependency on Micronaut Serialization that implements this.

The problem is not on the server but on the client (we inject a test resources client on the user classpath)

melix commented 2 years ago

@graemerocher this is how the client is created in test resources: https://github.com/micronaut-projects/micronaut-test-resources/blob/777315172fc31a0c28006a485e6564a97a0037f4/test-resources-client/src/main/java/io/micronaut/testresources/client/TestResourcesClientFactory.java#L53-L56

I don't think there's a way to pass in a different object mapper, is it? Or would it "simply work" in 4?

graemerocher commented 2 years ago

should be fine. DefaultHttpClient ultimately ends up calling:

    private static MediaTypeCodecRegistry createDefaultMediaTypeRegistry() {
        JsonMapper mapper = JsonMapper.createDefault();
        ApplicationConfiguration configuration = new ApplicationConfiguration();
        return MediaTypeCodecRegistry.of(
                new JsonMediaTypeCodec(mapper, configuration, null),
                new JsonStreamMediaTypeCodec(mapper, configuration, null)
        );
    }

Which calls JsonMapper.createDefault()

desmondblue commented 4 months ago

Hi @graemerocher @melix Context: using micronaut 4.5.3 / micronaut-jackson-databind 4.5.3 Thanks for this insightful talk I was myself running in an issue with micronaut-jackson-databind dependency since in one o the subprojects required micronat-platform-bom which in turn calls serde-api as a dependency and hence the Error instantiating bean of type [io.micronaut.jackson.databind.JacksonDatabindMapper]. So from what I summarize that the discussion to fix this issue is still on while a workaround fix would be to just use the fasterxml.jackson dependency directly rather than the micronaut one?