Skip to content

Regression in 3.13.0.CR1: Lambda expression from custom serializable interface used as @QuarkusTest method parameter fails with ClassNotFoundException #42006

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

Closed
famod opened this issue Jul 19, 2024 · 6 comments · Fixed by #34681
Assignees
Labels
Milestone

Comments

@famod
Copy link
Member

famod commented Jul 19, 2024

Describe the bug

Up until 3.12.3 you can create a lambda expression from something like:

    public interface SerializableCustom extends Serializable {
        String get();
    }

and pass it over to a @QuarkusTest method as a parameter, e.g.:

@QuarkusTest
public class LambdaParamTest {

    @ParameterizedTest
    @ArgumentsSource(LambdaProvider.class)
    void test(final SerializableCustom lambda) {
        // ...
    }

    private static class LambdaProvider implements ArgumentsProvider {

        @Override
        public Stream<? extends Arguments> provideArguments(final ExtensionContext context) {
            return Stream.of(Arguments.of((SerializableCustom) () -> "foobar"));
        }
    }

but with 3.13.0.CR1 you'll get:

java.lang.IllegalStateException: java.lang.ClassNotFoundException: org.acme.LambdaParamTest$LambdaProvider$$Lambda/0x00007fa1844f3158
	at io.quarkus.test.junit.internal.NewSerializingDeepClone.clone(NewSerializingDeepClone.java:132)
	[...]

Expected behavior

Cloning works for lambdas created from custom serializable interfaces.

Actual behavior

Exception is thrown.

How to Reproduce?

q_test-lambda.zip

  • ./mvnw clean test fails
  • ./mvnw clean test -Dquarkus.platform.version=3.12.3 passes

Note that the reproducer also includes a working lambda example for both versions (using a subclass of java.util.function.Supplier<T>).

Output of uname -a or ver

No response

Output of java -version

No response

Quarkus version or git rev

3.13.0.CR1

Build tool (ie. output of mvnw --version or gradlew --version)

No response

Additional information

I suppose this is related to #40906, /cc @holly-cummins

Workaround: Use anonymous class instead.

@famod famod added kind/bug Something isn't working area/testing labels Jul 19, 2024
Copy link

quarkus-bot bot commented Jul 19, 2024

/cc @matejvasek (amazon-lambda), @patriot1burke (amazon-lambda)

@gastaldi
Copy link
Contributor

gastaldi commented Jul 19, 2024

It seems to have been caused by #40601 (which was reverted in 3.12 before it was released and reverted back in 3.13)

/cc @dmlloyd

@famod
Copy link
Member Author

famod commented Jul 19, 2024

Btw, I'd prefer not having to add Serializable at all, but up to now it is/was the only way to pass lambdas as test method params.

@dmlloyd
Copy link
Member

dmlloyd commented Jul 19, 2024

You should be able to pass the argument as non-serializable now, and it should work. A more comprehensive solution (i.e. not serializing anymore) is being worked on in the meantime.

@famod
Copy link
Member Author

famod commented Jul 19, 2024

You should be able to pass the argument as non-serializable now, and it should work.

That's very valuable info, thanks! Could be something for the migration guide, no?

I'm a bit puzzled now why I didn't see that when starting the reproducer because I was first missing extends Serializable and got a null test method parameter - which went away after adding Serializable. I was probably still on 3.12.3 at that point. 🤔

But I do confirm that removing Serializable does make the test of the reproducer pass (with 3.13.0.CR1).
Sadly, when I apply the same fix to my actual project, I'm greeted with a ClassCastException which I have not yet managed to showcase in the reproducer:

CatalogDataTest.mandatoryMetadataComplete:78->lambda$3:80->lambda$4:81 » ClassCast class somepckg.persistence.entity.catalog.Contextualized$$Lambda/0x00007fee71cec000 cannot be cast to class somepckg.persistence.entity.catalog.CatalogValue$MetadataKey (somepckg.persistence.entity.catalog.Contextualized$$Lambda/0x00007fee71cec000 is in unnamed module of loader 'app'; somepckg.persistence.entity.catalog.CatalogValue$MetadataKey is in unnamed module of loader io.quarkus.bootstrap.classloading.QuarkusClassLoader @19324eab)

@famod
Copy link
Member Author

famod commented Sep 6, 2024

But I do confirm that removing Serializable does make the test of the reproducer pass (with 3.13.0.CR1). Sadly, when I apply the same fix to my actual project, I'm greeted with a ClassCastException which I have not yet managed to showcase in the reproducer:

CatalogDataTest.mandatoryMetadataComplete:78->lambda$3:80->lambda$4:81 » ClassCast class somepckg.persistence.entity.catalog.Contextualized$$Lambda/0x00007fee71cec000 cannot be cast to class somepckg.persistence.entity.catalog.CatalogValue$MetadataKey (somepckg.persistence.entity.catalog.Contextualized$$Lambda/0x00007fee71cec000 is in unnamed module of loader 'app'; somepckg.persistence.entity.catalog.CatalogValue$MetadataKey is in unnamed module of loader io.quarkus.bootstrap.classloading.QuarkusClassLoader @19324eab)

FWIW, this is still the case in 3.14.2 which contains #42916.

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

Successfully merging a pull request may close this issue.

4 participants