Handler not found for embedded jetty

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Handler not found for embedded jetty

David P
I want to use jetty to receive json POSTs, and use the values to call setters in another class that's part of a service.

Tests using curl return a 404, and dumping at jetty start reveals no routes from query paths to handlers. This seems to be the relevant section of the dump:

 += ServerConnector@25b485ba{HTTP/1.1,[http/1.1]}{0.0.0.0:8081} - STARTED
 |   +~ org.eclipse.jetty.server.Server@731f8236 - STARTING
 |   +~ qtp1113619023{STARTED,6<=6<=6,i=1,q=0} - STARTED
 |   += org.eclipse.jetty.util.thread.ScheduledExecutorScheduler@1188e820 - STARTED
 |   +- org.eclipse.jetty.io.ArrayByteBufferPool@240237d2
 |   += HttpConnectionFactory@33b37288[HTTP/1.1] - STARTED
 |   |   +- HttpConfiguration@25a65b77{32768/8192,8192/8192,https://:0,[]}
 |   += org.eclipse.jetty.server.ServerConnector$ServerConnectorManager@2ed0fbae - STARTED
 |   |   += org.eclipse.jetty.io.ManagedSelector@212bf671 id=0 keys=0 selected=0 id=0
 |   |   |   +- sun.nio.ch.EPollSelectorImpl@6298dace keys=0
 |   |   += org.eclipse.jetty.io.ManagedSelector@2aece37d id=1 keys=0 selected=0 id=1
 |   |       +- sun.nio.ch.EPollSelectorImpl@43668d89 keys=0
 |   +- sun.nio.ch.ServerSocketChannelImpl[/0:0:0:0:0:0:0:0:8081]
 |   +- qtp1113619023-24-acceptor-0@1b83efaf-ServerConnector@25b485ba{HTTP/1.1,[http/1.1]}{0.0.0.0:8081}
 
I've tried switching my context path and query path. How should I change my code so it handles a request like this?

    curl -d '{"name1":"value1", "name2":"value2"}' -H "Content-Type: application/json" -X POST http://localhost:8081/metadataForUtterance

Here's the code:

    //Adapted from https://www.baeldung.com/jetty-embedded
    // https://github.com/eugenp/tutorials/blob/master/libraries-server/src/main/java/com/baeldung/jetty/JettyServer.java

    import org.apache.log4j.Logger;
    import org.eclipse.jetty.server.Connector;
    import org.eclipse.jetty.server.Server;
    import org.eclipse.jetty.server.ServerConnector;
    import org.eclipse.jetty.servlet.ServletContextHandler;
    import org.eclipse.jetty.servlet.ServletHolder;
    import org.eclipse.jetty.util.thread.QueuedThreadPool;

    class JettyServer {
        private static final Logger s_oLogger = Logger.getLogger(JettyServer.class);

        private static final String s_sContextPath = "/";
        private static final String s_sQueryPath = "/metadataForUtterance";
        private static final int s_iPort = 8081;
        //When the two values below were both set to 1, the service log revealed:
        // java.lang.IllegalStateException: Insufficient threads: max=1 < needed(acceptors=1 + selectors=4 + request=1)
        private static final int s_iMaxThreads = 6;
        private static final int s_iMinThreads = 6;
        private static final int s_iMsecsIdleTimeout = 120;

        private Server _oServer;

        void start(MyFriendClass oFriendNeedingMetadata)
        throws Exception
        {
            QueuedThreadPool oThreadPool
                    = new QueuedThreadPool(
                            s_iMaxThreads,
                            s_iMinThreads,
                            s_iMsecsIdleTimeout
                    );

            _oServer = new Server( oThreadPool );

            //DEBUG
            // See https://www.eclipse.org/jetty/documentation/current/jetty-dump-tool.html
            oThreadPool.setDetailedDump(true);
            _oServer.setDumpAfterStart(true);

            ServerConnector oConnector = new ServerConnector( _oServer );
            oConnector.setPort( s_iPort );
            _oServer.setConnectors( new Connector[] { oConnector } );

            //Adapted from https://stackoverflow.com/a/39440430/6856046
            // in order to pass oFriendNeedingMetadata to the UtteranceMetadataFromPost instance.
            ServletContextHandler oContext = new ServletContextHandler();
            oContext.setContextPath( s_sContextPath );
            UtteranceMetadataFromPost oServletForMetadataPosts
                    = new UtteranceMetadataFromPost( oFriendNeedingMetadata );
            ServletHolder oServletHolder = new ServletHolder(oServletForMetadataPosts);
            oContext.addServlet(
                oServletHolder,
                s_sQueryPath
            );

            _oServer.start();

            s_oLogger.debug(
                "Started: s_sContextPath["+ s_sContextPath
                +"] s_iPort["+ s_iPort
                +"] s_sQueryPath["+ s_sQueryPath
                +"] s_iMaxThreads["+ s_iMaxThreads
                +"] s_iMinThreads["+ s_iMinThreads
                +"] s_iMsecsIdleTimeout["+ s_iMsecsIdleTimeout
                +"]."
            );
        }

        void stop() throws Exception {
            _oServer.stop();
        }
    }

Cheers,
David

Btw, I also tried following https://www.eclipse.org/jetty/documentation/current/advanced-embedding.html One problem there is that the uber jar is only ~500kB and seems corrupted every time I download it:

    curl -o jetty-all-uber.jar https://repo1.maven.org/maven2/org/eclipse/jetty/aggregate/jetty-all/9.4.18.v20190429/jetty-all-9.4.18.v20190429-uber.jar

_______________________________________________
jetty-users mailing list
[hidden email]
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://www.eclipse.org/mailman/listinfo/jetty-users
Reply | Threaded
Open this post in threaded view
|

Re: Handler not found for embedded jetty

Joakim Erdfelt-8
You created oContext but never really added it as a handler to your server.

Add this, before _oServer.start();

// import org.eclipse.jetty.server.handler.HandlerList;
// import org.eclipse.jetty.server.handler.DefaultHandler;
HandlerList handlers = new HandlerList();
handlers.addHandler(oContext);
handlers.addHandler(new DefaultHandler());
_oServer.setHandler(handlers);


Joakim Erdfelt / [hidden email]


On Tue, May 21, 2019 at 2:41 AM David P <[hidden email]> wrote:
I want to use jetty to receive json POSTs, and use the values to call setters in another class that's part of a service.

Tests using curl return a 404, and dumping at jetty start reveals no routes from query paths to handlers. This seems to be the relevant section of the dump:

 += ServerConnector@25b485ba{HTTP/1.1,[http/1.1]}{0.0.0.0:8081} - STARTED
 |   +~ org.eclipse.jetty.server.Server@731f8236 - STARTING
 |   +~ qtp1113619023{STARTED,6<=6<=6,i=1,q=0} - STARTED
 |   += org.eclipse.jetty.util.thread.ScheduledExecutorScheduler@1188e820 - STARTED
 |   +- org.eclipse.jetty.io.ArrayByteBufferPool@240237d2
 |   += HttpConnectionFactory@33b37288[HTTP/1.1] - STARTED
 |   |   +- HttpConfiguration@25a65b77{32768/8192,8192/8192,https://:0,[]}
 |   += org.eclipse.jetty.server.ServerConnector$ServerConnectorManager@2ed0fbae - STARTED
 |   |   += org.eclipse.jetty.io.ManagedSelector@212bf671 id=0 keys=0 selected=0 id=0
 |   |   |   +- sun.nio.ch.EPollSelectorImpl@6298dace keys=0
 |   |   += org.eclipse.jetty.io.ManagedSelector@2aece37d id=1 keys=0 selected=0 id=1
 |   |       +- sun.nio.ch.EPollSelectorImpl@43668d89 keys=0
 |   +- sun.nio.ch.ServerSocketChannelImpl[/0:0:0:0:0:0:0:0:8081]
 |   +- qtp1113619023-24-acceptor-0@1b83efaf-ServerConnector@25b485ba{HTTP/1.1,[http/1.1]}{0.0.0.0:8081}
 
I've tried switching my context path and query path. How should I change my code so it handles a request like this?

    curl -d '{"name1":"value1", "name2":"value2"}' -H "Content-Type: application/json" -X POST http://localhost:8081/metadataForUtterance

Here's the code:

    //Adapted from https://www.baeldung.com/jetty-embedded
    // https://github.com/eugenp/tutorials/blob/master/libraries-server/src/main/java/com/baeldung/jetty/JettyServer.java

    import org.apache.log4j.Logger;
    import org.eclipse.jetty.server.Connector;
    import org.eclipse.jetty.server.Server;
    import org.eclipse.jetty.server.ServerConnector;
    import org.eclipse.jetty.servlet.ServletContextHandler;
    import org.eclipse.jetty.servlet.ServletHolder;
    import org.eclipse.jetty.util.thread.QueuedThreadPool;

    class JettyServer {
        private static final Logger s_oLogger = Logger.getLogger(JettyServer.class);

        private static final String s_sContextPath = "/";
        private static final String s_sQueryPath = "/metadataForUtterance";
        private static final int s_iPort = 8081;
        //When the two values below were both set to 1, the service log revealed:
        // java.lang.IllegalStateException: Insufficient threads: max=1 < needed(acceptors=1 + selectors=4 + request=1)
        private static final int s_iMaxThreads = 6;
        private static final int s_iMinThreads = 6;
        private static final int s_iMsecsIdleTimeout = 120;

        private Server _oServer;

        void start(MyFriendClass oFriendNeedingMetadata)
        throws Exception
        {
            QueuedThreadPool oThreadPool
                    = new QueuedThreadPool(
                            s_iMaxThreads,
                            s_iMinThreads,
                            s_iMsecsIdleTimeout
                    );

            _oServer = new Server( oThreadPool );

            //DEBUG
            // See https://www.eclipse.org/jetty/documentation/current/jetty-dump-tool.html
            oThreadPool.setDetailedDump(true);
            _oServer.setDumpAfterStart(true);

            ServerConnector oConnector = new ServerConnector( _oServer );
            oConnector.setPort( s_iPort );
            _oServer.setConnectors( new Connector[] { oConnector } );

            //Adapted from https://stackoverflow.com/a/39440430/6856046
            // in order to pass oFriendNeedingMetadata to the UtteranceMetadataFromPost instance.
            ServletContextHandler oContext = new ServletContextHandler();
            oContext.setContextPath( s_sContextPath );
            UtteranceMetadataFromPost oServletForMetadataPosts
                    = new UtteranceMetadataFromPost( oFriendNeedingMetadata );
            ServletHolder oServletHolder = new ServletHolder(oServletForMetadataPosts);
            oContext.addServlet(
                oServletHolder,
                s_sQueryPath
            );

            _oServer.start();

            s_oLogger.debug(
                "Started: s_sContextPath["+ s_sContextPath
                +"] s_iPort["+ s_iPort
                +"] s_sQueryPath["+ s_sQueryPath
                +"] s_iMaxThreads["+ s_iMaxThreads
                +"] s_iMinThreads["+ s_iMinThreads
                +"] s_iMsecsIdleTimeout["+ s_iMsecsIdleTimeout
                +"]."
            );
        }

        void stop() throws Exception {
            _oServer.stop();
        }
    }

Cheers,
David

Btw, I also tried following https://www.eclipse.org/jetty/documentation/current/advanced-embedding.html One problem there is that the uber jar is only ~500kB and seems corrupted every time I download it:

    curl -o jetty-all-uber.jar https://repo1.maven.org/maven2/org/eclipse/jetty/aggregate/jetty-all/9.4.18.v20190429/jetty-all-9.4.18.v20190429-uber.jar
_______________________________________________
jetty-users mailing list
[hidden email]
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://www.eclipse.org/mailman/listinfo/jetty-users

_______________________________________________
jetty-users mailing list
[hidden email]
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://www.eclipse.org/mailman/listinfo/jetty-users
Reply | Threaded
Open this post in threaded view
|

Re: Handler not found for embedded jetty

David P
Thank you. My dump now shows the mapping of my query path to my handler class:

     += org.eclipse.jetty.server.handler.HandlerList@501edcf1[o.e.j.s.ServletContextHandler@2890c451{/,null,AVAILABLE}, org.eclipse.jetty.server.handler.DefaultHandler@78b729e6] - STARTED
     |   += o.e.j.s.ServletContextHandler@2890c451{/,null,AVAILABLE} - STARTED
     |   |   += org.eclipse.jetty.servlet.ServletHandler@6b4a4e18 - STARTED
     |   |   |   += com.example.UtteranceMetadataFromPost-6591f517@254ec81d==com.example.UtteranceMetadataFromPost,jsp=null,order=-1,inst=true - STARTED
     |   |   |   +- [/metadataForUtterance]=>com.example.UtteranceMetadataFromPost-6591f517
     |   |   |   += org.eclipse.jetty.servlet.ServletHandler$Default404Servlet-53ca01a2@170224c2==org.eclipse.jetty.servlet.ServletHandler$Default404Servlet,jsp=null,order=-1,inst=false - STARTED
     |   |   |   +- [/]=>org.eclipse.jetty.servlet.ServletHandler$Default404Servlet-53ca01a2
     |   |   |
     |   |   +> No ClassLoader
     |   |   +> Handler attributes o.e.j.s.ServletContextHandler@2890c451{/,null,AVAILABLE}
     |   |   |   +- org.eclipse.jetty.server.Executor=qtp1414147750{STARTED,6<=6<=6,i=1,q=0}
     |   |   +> Context attributes o.e.j.s.ServletContextHandler@2890c451{/,null,AVAILABLE}
     |   |   |   +- org.eclipse.jetty.util.DecoratedObjectFactory=org.eclipse.jetty.util.DecoratedObjectFactory[decorators=1]
     |   |   +> Initparams o.e.j.s.ServletContextHandler@2890c451{/,null,AVAILABLE}
     |   += org.eclipse.jetty.server.handler.DefaultHandler@78b729e6 - STARTED

and now my curl test works.

On Tue, May 21, 2019 at 10:29 PM Joakim Erdfelt <[hidden email]> wrote:
You created oContext but never really added it as a handler to your server.

Add this, before _oServer.start();

// import org.eclipse.jetty.server.handler.HandlerList;
// import org.eclipse.jetty.server.handler.DefaultHandler;
HandlerList handlers = new HandlerList();
handlers.addHandler(oContext);
handlers.addHandler(new DefaultHandler());
_oServer.setHandler(handlers);

_______________________________________________
jetty-users mailing list
[hidden email]
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://www.eclipse.org/mailman/listinfo/jetty-users