Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [jetty-users] WebSockets JSR 356, war files and Embedded Jetty

Hi Joakim,

Again thanks for your comments. I have solved my original problem, and now the small webapp runs correctly from my original war file loaded into Embedded Jetty. I do not understand the fine detail, but I checked configuration possibilities and added code that you have discussed elsewhere. I include the code to perhaps benefit others. (You may have a comment to make. - note that 'new AnnotationConfiguration()' is first cab off the rank.) The code is based on a Jetty example, and items of interest are points 1, 2 and 3.

Thanks for help.
Regards
Goffredo


public class OneWebSocketApp {

    public static void main(String[] args) throws Exception {

        Server server = new Server(8080);

        WebAppContext webapp = new WebAppContext();

        // 1. set context path
        webapp.setContextPath("/ProgrammaticWebSocketEcho");

        // 2. enable WebSockets flag
webapp.setAttribute("org.eclipse.jetty.websocket.jsr356", Boolean.TRUE);

        // 3. set all default configurations
        webapp.setConfigurations(new Configuration[] {
            new AnnotationConfiguration(),
            new WebXmlConfiguration(),
            new WebInfConfiguration(),
            new PlusConfiguration(),
            new MetaInfConfiguration(),
            new FragmentConfiguration(),
            new EnvConfiguration()
        });

        // define .war file
        File warFile = new File("src/webapps/ProgrammaticWebSocketEcho.war");

        webapp.setWar(warFile.getAbsolutePath());

        server.setHandler(webapp);

        // Start things up!
        server.start();

        server.dumpStdErr();
        server.join();
    }
}












Quoting Joakim Erdfelt <joakim@xxxxxxxxxxx>:

Still need bytecode/annotation scanning, as you are using
ServerApplicationConfig, which is initialized via a
ServletContainerInitializer, which requires bytecode/annotation scanning.

You have a few alternatives.

1) Enable the bytecode/annotation scanning as recommended in the previous
reply.


2) Use a ServletContextListener to trigger your endpoint additions to the
ServerContainer.

package jetty.websocket;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletException;
import javax.websocket.DeploymentException;
import javax.websocket.OnMessage;
import javax.websocket.server.ServerContainer;
import javax.websocket.server.ServerEndpoint;

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import
org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer;

public class JsrManualEndpointInit
{
    @ServerEndpoint(value="/echo")
    public static class EchoSocket
    {
        @OnMessage
        public String onMessage(String msg)
        {
            return msg;
        }
    }

    public static class AddEndpointsListener implements
ServletContextListener
    {
        @Override
        public void contextInitialized(ServletContextEvent sce)
        {
            ServerContainer container = (ServerContainer)
sce.getServletContext()
                    .getAttribute(ServerContainer.class.getName());

            try
            {
                container.addEndpoint(EchoSocket.class);
            }
            catch (DeploymentException e)
            {
                throw new RuntimeException("Unable to add WebSocket
Endpoints", e);
            }
        }

        @Override
        public void contextDestroyed(ServletContextEvent sce)
        {
        }
    }

    public static void main(String[] args) throws Exception
    {
        Server server = new Server(8080);

        ServletContextHandler context = new ServletContextHandler();
        context.setContextPath("/");
        context.addEventListener(new AddEndpointsListener());

        WebSocketServerContainerInitializer.configureContext(context);

        server.setHandler(context);

        server.start();
    }
}



3) Or initialize the ServerContainer during embedded setup and then pass in
the endpoints at that point.

Look at the examples -
https://github.com/jetty-project/embedded-jetty-websocket-examples/blob/master/javax.websocket-example/src/main/java/org/eclipse/jetty/demo/EventServer.java#L27-L31

package jetty.websocket;

import javax.websocket.OnMessage;
import javax.websocket.server.ServerContainer;
import javax.websocket.server.ServerEndpoint;

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import
org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer;

public class JsrManualEndpointInit
{
    @ServerEndpoint(value="/echo")
    public static class EchoSocket
    {
        @OnMessage
        public String onMessage(String msg)
        {
            return msg;
        }
    }

    public static void main(String[] args) throws Exception
    {
        Server server = new Server(8080);

        ServletContextHandler context = new ServletContextHandler();
        context.setContextPath("/");

        ServerContainer serverContainer =
WebSocketServerContainerInitializer.configureContext(context);
        serverContainer.addEndpoint(EchoSocket.class);

        server.setHandler(context);

        server.start();
    }
}





Joakim Erdfelt / joakim@xxxxxxxxxxx

On Tue, Apr 4, 2017 at 7:47 AM, <goffredo@xxxxxxxxxxx> wrote:

Hi Joakim,

Thanks for your reply. Sorry, I did not provide enough information, the
only item in my lib directory is: WEB-INF/lib/javax.websocket-api-1.1.jar,
nothing else. Also I am not using WebSocket annotations, just the
programmatic classes listed below, therefore adding annotations may not be
appropriate. I appreciate that Embedded Jetty needs heavy configuration,
but I am at a loss even after trying to looking into your suggestions. Most
of the examples I have seen assume I have access to my endpoint from within
OneWebApp (or similar), but I do not since it is in the war file. The
configuration for Embedded Jetty with a websocket war has me beat. For
interest, code for the simple webapp is below.

I am hoping for an easy answer :)
Regards
Goffredo


------

package jwsp.chapter1;

import java.io.IOException;
import javax.websocket.Endpoint;
import javax.websocket.EndpointConfig;
import javax.websocket.MessageHandler;
import javax.websocket.Session;

public class ProgrammaticEchoServer extends Endpoint {

    @Override
    public void onOpen(Session session, EndpointConfig endpointConfig) {
        final Session mySession = session;
        mySession.addMessageHandler(new MessageHandler.Whole<String>() {
            @Override
            public void onMessage(String text) {
                try {
                    mySession.getBasicRemote().sendText("I got this (" +
text + ") so I am sending it back !");
                } catch (IOException ioe) {
                    System.out.println("oh dear, something went wrong
trying to send the message back: " + ioe.getMessage());
                }
            }
        });
    }

}


package jwsp.chapter1;

import java.util.HashSet;
import java.util.Set;
import javax.websocket.Endpoint;
import javax.websocket.server.*;

public class ProgrammaticEchoServerAppConfig implements
ServerApplicationConfig {

    @Override
    public Set<ServerEndpointConfig> getEndpointConfigs(Set<Class<?
extends Endpoint>> endpointClasses) {
        Set configs = new HashSet<ServerEndpointConfig>();
        ServerEndpointConfig sec = ServerEndpointConfig.Builder
.create(ProgrammaticEchoServer.class,
"/programmaticecho")
                                            .build();
        configs.add(sec);
        return configs;
    }

    @Override
    public Set<Class<?>> getAnnotatedEndpointClasses(Set<Class<?>>
scanned) {
        return scanned;

    }
}





Quoting Joakim Erdfelt <joakim@xxxxxxxxxxx>:

First, Tyrus is for containers that don't have their own WebSocket
implementation.

Jetty (and Tomcat) both implement JSR356 natively, use those, not Tyrus.

Jetty, unlike Tomcat, is a modular container, everything is optional (even
the Server!).
When you go standalone, the modules are glued together to fit the various
specs most people are comfortable with.
When you go embedded, all of that glue is now on you to piece together to
suit your needs specifically.
What is likely happening, is that you are including Tyrus (don't), and
have
not enabled the Annotation scanning.

To enable annotations ...

  org.eclipse.jetty.webapp.Configuration.ClassList classlist =
org.eclipse.jetty.webapp.Configuration.ClassList.setServerDe
fault(server);
  classlist.addAfter("org.eclipse.jetty.webapp.FragmentConfiguration",
     "org.eclipse.jetty.plus.webapp.EnvConfiguration",
     "org.eclipse.jetty.plus.webapp.PlusConfiguration");
  classlist.addBefore("org.eclipse.jetty.webapp.JettyWebXmlCon
figuration",
    "org.eclipse.jetty.annotations.AnnotationConfiguration");

Try that first.

Otherwise you can look at the embedded-jetty examples below ...

https://github.com/jetty-project/embedded-jetty-cookbook/
tree/master/src/main/java/org/eclipse/jetty/cookbook/websocket/jsr/
https://github.com/jetty-project/embedded-jetty-websocket-examples
https://github.com/jetty-project/embedded-servlet-3.1


Joakim Erdfelt / joakim@xxxxxxxxxxx

On Sun, Apr 2, 2017 at 6:47 PM, <goffredo@xxxxxxxxxxx> wrote:


Hi,

I have been trying to load (into Jetty Embedded) the simple Echo example
as presented by Danny Coward in the first chapter of his book Java
WebSocket Programming (Oracle Press). His program is a variant of the
standard echo example presented on the Tyrus site also. I use Eclipse
Neon.
I am not using Jetty WebSockets, rather I am using the Java JSR 356
WebSockets implementation. Also, I have no trouble with the embedded
Jetty
WebSockets examples, but I am trying to load a war file.

The program Danny presents works fine on current Tomcat, and as a war
file, it also works fine on a standalone current Jetty. My problem is I
am
unable to take the exact same WebSockets war file that works OK on
standalone Jetty and load it successfully into the Embedded Jetty. I do
not
know where to look, or what to do. Is it a setting problem? Or a Thread
problem? Or ... If someone can point me in the right direction I would be
thankful.

Regards
Goffredo


_______________________________________________
jetty-users mailing list
jetty-users@xxxxxxxxxxx
To change your delivery options, retrieve your password, or unsubscribe
from this list, visit
https://dev.eclipse.org/mailman/listinfo/jetty-users



_______________________________________________
jetty-users mailing list
jetty-users@xxxxxxxxxxx
To change your delivery options, retrieve your password, or unsubscribe
from this list, visit
https://dev.eclipse.org/mailman/listinfo/jetty-users





Back to the top