Skip to content
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

Javalin with JPMS and ServiceLoader results in NoClassDefFoundError: kotlin/NoWhenBranchMatchedException #1624

Closed
baumgarb opened this issue Jul 26, 2022 · 10 comments

Comments

@baumgarb
Copy link

Actual behavior (the bug)
Running Javalin with JPMS and ServiceLoader leads to the a NoClassDefFoundError. If I run the very same application not as a module and without the service loader everything works just fine.

Expected behavior
I'm expecting Javalin to work with JPMS and ServiceLoader the same way it does for a console application without Javalin. If you run the console application in the same project everything works out just fine.

To Reproduce

  • (✓) Clone no-jpms-and-serviceloader branch and you'll see everything works fine.

  • (✓) Run console app in very same project and you'll see everything works fine as well with ServiceLoader and JPMS in place.

    .\gradlew.bat :client:run
    
  • (✗) Clone main branch and follow README.md to step 3 and you well end up with the exception:

    > Task :api:run FAILED
    [main] INFO org.example.api.WebAPI - Hello World from WebAPI, yay :-)
    Exception in thread "main" java.lang.NoClassDefFoundError: kotlin/NoWhenBranchMatchedException
            at io.javalin@4.6.4/io.javalin.core.JavalinConfig$Inner.<init>(JavalinConfig.java:77)
            at io.javalin@4.6.4/io.javalin.core.JavalinConfig.<init>(JavalinConfig.java:67)
            at io.javalin@4.6.4/io.javalin.Javalin.<init>(Javalin.java:54)
            at io.javalin@4.6.4/io.javalin.Javalin.create(Javalin.java:91)
            at io.javalin@4.6.4/io.javalin.Javalin.create(Javalin.java:78)
            at org.example.api/org.example.api.WebAPI.main(WebAPI.java:24)
    Caused by: java.lang.ClassNotFoundException: kotlin.NoWhenBranchMatchedException
            at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
            at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
            at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
            ... 6 more
    FAILURE: Build failed with an exception.
    

Additional context
n/a

@tipsy
Copy link
Member

tipsy commented Jul 26, 2022

@baumgarb java.lang.NoClassDefFoundError: kotlin/NoWhenBranchMatchedException looks like it's more Kotlin related than Javalin related. Have you tried using JPMS with any other Kotlin based JVM project?

@tipsy
Copy link
Member

tipsy commented Jul 26, 2022

You could check out https://github.com/vihangpatil/kotlin-modules ?

@baumgarb
Copy link
Author

@tipsy haven't mixed in any Kotlin based libraries or projects into my Java 9+ Gradle and JPMS projects yet. That's a first and probably you're right.

I'll have a look at https://github.com/vihangpatil/kotlin-modules and let's see if I can figure out something.

Thank you very much either way :-)

@dzikoysk
Copy link
Member

Kotlin stdlib supports modules since 1.4+, but Javalin does not export dedicated module-info with library, so in theory it's should work in unnamed module. Because this class cannot be found, you have to find a way to link kotlin stdlib in your project.

@tipsy tipsy added the INFO label Jul 27, 2022
@baumgarb
Copy link
Author

baumgarb commented Aug 2, 2022

Issue's solved now, I've pushed a new branch showing how to make it work, see main-solved. If you don't want to bother looking at the latest commit 1f80fc7 of this branch then here's the solution: simply add this line to the module-info.java of the api project:

    requires io.javalin;
    requires com.fasterxml.jackson.databind;
    requires org.slf4j.simple;
    requires kotlin.stdlib;                        <-- simply add this line here

    uses org.example.services.api.PersonReader;

The root cause seems to be that Javalin is not modularized yet. If you look closer into the module resolution (pass --show-module-resolution arg to java) you will see that Javalin is treated as an automatic module and the auto-generated requires statements for this automatic module do not include kotlin.stdlib.

Thanks a lot to @rraumberger who helped me getting to the bottom of this and came up with the solution, but is too shy to post it here :-P

@tipsy
Copy link
Member

tipsy commented Aug 2, 2022

The root cause seems to be that Javalin is not modularized yet. If you look closer into the module resolution (pass --show-module-resolution arg to java) you will see that Javalin is treated as an automatic module and the auto-generated requires statements for this automatic module do not include kotlin.stdlib.

Do you happen to know what we can do in Javalin to fix this?

Thanks a lot to @rraumberger who helped me getting to the bottom of this and came up with the solution, but is too shy to post it here :-P

He sounds like a great guy!

Issue's solved now, I've pushed a new branch showing how to make it work, see main-solved.

Might make an interesting tutorial for https://javalin.io/tutorials, if you're interested in writing one?

@baumgarb
Copy link
Author

baumgarb commented Aug 2, 2022

Do you happen to know what we can do in Javalin to fix this?

Not off top of my head, I will take a look, maybe there's a quick win we can achieve other than fully introducing modules in the repo.

He sounds like a great guy!

You seem to have a great gut feeling, indeed he is 👍 :-D

Might make an interesting tutorial if you're interested in writing one?

Oh it would be my pleasure, I'd be honored to contribute and I'll definitely do so, thx for offering :-)

@baumgarb
Copy link
Author

baumgarb commented Aug 8, 2022

@tipsy FYI, I've created a PR for adding a tutorial on javalin.io on how to setup a bare bone Gradle project with Javalin & JPMS which also makes use of the new ServiceLoader infrastructure. See PR javalin/website#136.

@tipsy
Copy link
Member

tipsy commented Aug 9, 2022

@baumgarb that's a really well written tutorial @baumgarb, thank you !

@tipsy
Copy link
Member

tipsy commented Aug 9, 2022

I'll also close this now :)

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

No branches or pull requests

3 participants