Search code examples
jodd

jodd and jetty classNotFound (org.eclipse.jetty.client.api.Result)


I have an app build with jodd 3.6.6 and when I try to run it on jetty9 it cannot initialize Madvoc :

    1377 [ERROR] j.m.Madvoc.startNewWebApplication:161 - Madvoc startup failure.
jodd.madvoc.MadvocException: Scan classpath error; <--- java.lang.ClassNotFoundException: Class not found: org.eclipse.jetty.client.api.Result
    at jodd.madvoc.config.AutomagicMadvocConfigurator.configure(AutomagicMadvocConfigurator.java:85)
    at jodd.madvoc.config.AutomagicMadvocConfigurator.configure(AutomagicMadvocConfigurator.java:65)
    at jodd.madvoc.WebApplication.configure(WebApplication.java:255)
    at jodd.madvoc.Madvoc.start(Madvoc.java:238)
    at jodd.madvoc.Madvoc.startNewWebApplication(Madvoc.java:157)
    at jodd.madvoc.MadvocServletFilter.init(MadvocServletFilter.java:45)
    at org.eclipse.jetty.servlet.FilterHolder.initialize(FilterHolder.java:138)
    at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:852)
    at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:298)
    at org.eclipse.jetty.webapp.WebAppContext.startWebapp(WebAppContext.java:1349)
    at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1342)
    at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:741)
    at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:505)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
    at org.eclipse.jetty.server.Server.start(Server.java:387)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:114)
    at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
    at org.eclipse.jetty.server.Server.doStart(Server.java:354)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at net.sourceforge.eclipsejetty.starter.jetty9.Jetty9Adapter.start(Jetty9Adapter.java:68)
    at net.sourceforge.eclipsejetty.starter.common.AbstractJettyLauncherMain.launch(AbstractJettyLauncherMain.java:85)
    at net.sourceforge.eclipsejetty.starter.jetty9.Jetty9LauncherMain.main(Jetty9LauncherMain.java:42)
Caused by: jodd.io.findfile.FindFileException: Scan entry error: EntryData{org.eclipse.jetty.client.api.Result'}; <--- java.lang.ClassNotFoundException: Class not found: org.eclipse.jetty.client.api.Result
    at jodd.io.findfile.ClassFinder.scanEntry(ClassFinder.java:391)
    at jodd.io.findfile.ClassFinder.scanJarFile(ClassFinder.java:292)
    at jodd.io.findfile.ClassFinder.scanPath(ClassFinder.java:261)
    at jodd.io.findfile.ClassFinder.scanPaths(ClassFinder.java:226)
    at jodd.madvoc.config.AutomagicMadvocConfigurator.configure(AutomagicMadvocConfigurator.java:83)
    ... 22 more
Caused by: jodd.madvoc.MadvocException: Invalid Madvoc result class: org.eclipse.jetty.client.api.Result; <--- java.lang.ClassNotFoundException: Class not found: org.eclipse.jetty.client.api.Result
    at jodd.madvoc.config.AutomagicMadvocConfigurator.onEntry(AutomagicMadvocConfigurator.java:108)
    at jodd.io.findfile.ClassFinder.scanEntry(ClassFinder.java:389)
    ... 26 more

The same app runs without a problem on tomcat. Any idea ?


Solution

  • Ok, it should be simple: just skip the scanning of netty classes.

    Here is the explanation: In Madvoc you can optionally use the Result class (source) to work with the results (documentation). In short, if you have a field with Result type, Madvoc will use it for this feature.

    So it looks like Netty has the same class name, hence the error. To prevent this (until we make a better recognition), just skip scanning the full class path, and make the scanner scan only your classes - that will improve the startup performances too. Here is how to do that:

    By default, the AutomagicMadvocConfigurator is used for configuring the actions (by scanning the path). Get this instance (in WebApplication for example) and configure it (since it is a ClassFinder subclass). So what I do is:

    classFinder.setExcludeAllEntries(true);
    classFinder.setIncludedEntries(myapp.getClass().getPackage().getName() + ".*");
    classFinder.setIncludedJars("somejar.jar", "myapp*.jar");
    

    This will narrow down the classpath that is being searched.

    Let me know if you need more help with this. Meanwhile, we will definitely make changes so this never happens again!