Chris Kessel
Chris Kessel

Reputation: 5875

Embedded Jetty (v9) and jetty-env.xml create weird class loader issue

I'm programatically starting Jetty that points at a war. I also have a jetty-env.xml in the WEB-INF that defines a JNDI source. However, on startup, it gives me an error about class loader issues. I think because the main() creates one WebAppContext from java's AppClassLoader and the JNDI is in a WebAppContext defined in the jetty-env.xml.

java.lang.IllegalArgumentException: Object of class 'org.eclipse.jetty.webapp.WebAppContext' is not of type 'org.eclipse.jetty.webapp.WebAppContext'. Object Class and type Class are from different loaders. in file:/home/ckessel/Projects/exploded-war/WEB-INF/jetty-env.xml

I wouldn't think combining an embedded Jetty startup with an jetty-env.xml is that bizarre, but I've read through a ton of the eclipse Jetty docs on embedded Jetty and JNDI and so forth, but it doesn't seem to cover this combination.

An ideas?

The jetty-env.xml:

<Configure class="org.eclipse.jetty.webapp.WebAppContext">
    <New id="postgreSQL Datasource" class="org.eclipse.jetty.plus.jndi.Resource">
        <Arg></Arg>
        <Arg>jdbc/postgres</Arg>
        <Arg>
...postgres config stuff here...
        </Arg>
    </New>
</Configure>

The main()...the classlist stuff was stolen from http://www.eclipse.org/jetty/documentation/current/jndi-embedded.html

   public static void main(String[] args) throws Exception {
        int port = 8080;
        System.setProperty("org.eclipse.jetty.LEVEL", "DEBUG");
        System.setProperty("org.eclipse.jetty.util.log.class", "org.eclipse.jetty.util.log.StdErrLog");
        Server server = new Server(port);

        // Enable parsing of jndi-related parts of web.xml and jetty-env.xml
        Configuration.ClassList classlist = Configuration.ClassList.setServerDefault(server);
        classlist.addAfter(
                "org.eclipse.jetty.webapp.FragmentConfiguration",
                "org.eclipse.jetty.plus.webapp.EnvConfiguration",
                "org.eclipse.jetty.plus.webapp.PlusConfiguration");

        // Create the webapp for our war.
        WebAppContext webapp = new WebAppContext();
        webapp.setWar("/home/ckessel/Projects/build/exploded-war");
        webapp.setContextPath("/");
        server.setHandler(webapp);

        server.start();
        server.join();
    }

Upvotes: 0

Views: 966

Answers (1)

Joakim Erdfelt
Joakim Erdfelt

Reputation: 49462

2 things for you to do.

  1. Get rid of duplicate jars in your war's WEB-INF/lib directory. Mainly the jetty-webapp.jar it shouldn't be there.

  2. If you are only ever going to run 1 webapp in this embedded jetty instance, then consider using WebAppContext.setParentLoaderPriority(true), to make the ClassLoader behavior more akin to standard Java (as opposed to the reverse requirements for Servlets)

Upvotes: 1

Related Questions