Skip to content

Bad class file when compiling Micronaut 4.8.1 project #11749

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

Open
goeh opened this issue Apr 16, 2025 · 6 comments
Open

Bad class file when compiling Micronaut 4.8.1 project #11749

goeh opened this issue Apr 16, 2025 · 6 comments
Assignees
Labels

Comments

@goeh
Copy link
Contributor

goeh commented Apr 16, 2025

Expected Behavior

The project should compile without errors

Actual Behaviour

I tried to upgrade a project from Micronaut 4.8.0 to 4.8.1 but it fails to compile.

error: cannot access MyAuthenticationClient$Intercepted
  bad class file: .../micronaut/issues/bad-class-file/build/classes/java/main/com/example/MyAuthenticationClient$Intercepted.class
    undeclared type variable: T
    Please remove or make sure it appears in the correct subdirectory of the classpath.
1 error

I see the same problem in multiple projects.

Steps To Reproduce

  1. See simple reproducer project
  2. Try to compile with ./gradlew build
  3. See error

Environment Information

  • MacOS 15.3.2
  • JDK 21.0.2

Example Application

https://github.com/goeh/bad-class-file

Version

4.8.1

@altro3
Copy link
Contributor

altro3 commented Apr 16, 2025

@graemerocher @dstepanov Confirm this bug. Micronaut-core 4.8.10 is broken. I have same error when I tried to update to micronaut-platform 4.8.1.

Looks like the bug with return types with generics, like Mono<SimpleModel>.

From micronaut-openapi:

  1. Generated controller interface:
@Generated("io.micronaut.openapi.generator.JavaMicronautServerCodegen")
@Controller
public interface RequestBodyApi {

    /**
     * A method to send a simple model in body
     *
     * @param simpleModel (optional)
     * @return Success (status code 200)
     *         or An unexpected error has occurred (status code default)
     */
    @Post("/sendSimpleModel")
    Mono<@Valid SimpleModel> sendSimpleModel(
        @Body @Nullable(inherited = true) @Valid SimpleModel simpleModel
    );

....
}
  1. Introspection with micronaut-core 4.8.9:
@Generated
class $RequestBodyController$Definition$Intercepted extends RequestBodyController implements Intercepted {
    private final Interceptor[][] $interceptors;
    private final ExecutableMethod[] $proxyMethods;
    private final RequestBodyController $target;

    public Mono $$access$$sendSimpleModel(SimpleModel simpleModel) {
        return super.sendSimpleModel(simpleModel);
    }

    public Mono sendSimpleModel(SimpleModel simpleModel) {
        return (Mono)(new MethodInterceptorChain(this.$interceptors[0], this, this.$proxyMethods[0], new Object[]{simpleModel})).proceed();
    }

....
}
  1. Introspection with micronaut-core 4.8.10:
// $FF: synthetic class
@Generated
class $RequestBodyController$Definition$Intercepted extends RequestBodyController implements Intercepted {
    private final Interceptor[][] $interceptors;
    private final ExecutableMethod[] $proxyMethods;
    private final RequestBodyController $target;

    public Mono<T> $$access$$sendSimpleModel(SimpleModel simpleModel) {
        return super.sendSimpleModel(simpleModel);
    }

    public Mono<T> sendSimpleModel(SimpleModel simpleModel) {
        return (Mono)(new MethodInterceptorChain(this.$interceptors[0], this, this.$proxyMethods[0], new Object[]{simpleModel})).proceed();
    }

....
}

As you see, with micronaut-core 4.8.10 generated $RequestBodyController$Definition$Intercepted class has wrong return types - Mono<T>, but must be Mono as with micronaut-core 4.8.9

@etremblay
Copy link

etremblay commented Apr 16, 2025

It may be related. We have a similar error since 4.8.1

import io.micronaut.context.annotation.ConfigurationProperties
import io.micronaut.core.bind.annotation.Bindable

@ConfigurationProperties("application.split-io")
interface SplitIoConfiguration {
    @get:Bindable(defaultValue = "false")
    val enabled: Boolean

    val apiKey: String

    @get:Bindable(defaultValue = "10000")
    val blockUntilReadyTimeout: Int
}
error: cannot access SplitIoConfiguration$Intercepted
  bad class file: /home/edtremblay/kronos/projects/kotlin-lib/feature-splitio-micronaut/build/tmp/kapt3/classes/main/com/equisoft/feature/splitio/micronaut/context/SplitIoConfiguration$Intercepted.class
    undeclared type variable: E
    Please remove or make sure it appears in the correct subdirectory of the classpath.

Similar interfaces do not produce de same problem.

Generate code is

// $FF: synthetic class
@Generated
class SplitIoConfiguration$Intercepted implements SplitIoConfiguration, Introduced {
    private final Interceptor[][] $interceptors;
    private final ExecutableMethod[] $proxyMethods;

    public int getBlockUntilReadyTimeout() {
        return ((Number)(new MethodInterceptorChain(this.$interceptors[0], this, this.$proxyMethods[0])).proceed()).intValue();
    }

    public String getApiKey() {
        return (String)(new MethodInterceptorChain(this.$interceptors[1], this, this.$proxyMethods[1])).proceed();
    }

    public boolean getEnabled() {
        return (Boolean)(new MethodInterceptorChain(this.$interceptors[2], this, this.$proxyMethods[2])).proceed();
    }

    SplitIoConfiguration$Intercepted(BeanResolutionContext arg1, BeanContext arg2, Qualifier arg3, List<E> arg4, InterceptorRegistry arg5) {
        .SplitIoConfiguration.Intercepted.Definition.Exec executableMethods = new .SplitIoConfiguration.Intercepted.Definition.Exec();
        this.$proxyMethods = new ExecutableMethod[]{executableMethods.getExecutableMethodByIndex(0), executableMethods.getExecutableMethodByIndex(1), executableMethods.getExecutableMethodByIndex(2)};
        this.$interceptors = new Interceptor[][]{InterceptorChain.resolveIntroductionInterceptors(arg5, this.$proxyMethods[0], arg4), InterceptorChain.resolveIntroductionInterceptors(arg5, this.$proxyMethods[1], arg4), InterceptorChain.resolveIntroductionInterceptors(arg5, this.$proxyMethods[2], arg4)};
    }
}

@graemerocher
Copy link
Contributor

@dstepanov can you take a look?

@etremblay
Copy link

For us, it is fixed in 4.8.2

@altro3
Copy link
Contributor

altro3 commented Apr 18, 2025

Confirmed: all works fine with micronaut platform 4.8.2

@goeh
Copy link
Contributor Author

goeh commented Apr 18, 2025

Same here, 4.8.2 seems to works fine. Thanks for the fast response!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: Todo
Development

No branches or pull requests

5 participants