Making a Java EE 7 WebSocket ServerEndpoint class discoverable

The problem

Is your @ServerEndpoint annotated class not discoverable? Does the server log not contain any erroneous entries for you to examine? Your ClientEndpoint trying to connect to the server has most likely thrown a javax.websocket.DeploymentException in your face with a wrapped cause: org.glassfish.tyrus.websockets.HandshakeException. This last exception has a message for you:

Response code was not 101: 404

The message isn’t that cryptic, really. HTTP 1.1 status code 101 is something the WebSocket client rightfully expect. The server has to send that status code if he, during the handskake process, is willing to upgrade the currently used application protocol (HTTP!) into a WebSocket. But as the exception message reveals, the server sent a 404 code instead, saying that the resource our client was looking for couldn’t be found.

The solution

If you’re dead sure that your POJO is annoted with a @ServerEndpoint annotation, and that the required value element has been provided, then I think you have a packaging problem. Not that uncommon in the world of Java!

Let’s have a look at what the Java API for WebSocket specification (JSR-356) says, on page 25:

The class files for the endpoints and any resources they need such as text or image files are packaged into the Java EE-defined WAR file, either directly under WEB-INF/classes or packaged as a JAR file and located under WEB-INF/lib.

Java EE containers are not required to support deployment of websocket endpoints if they are not packaged in a WAR file as described above.

For my part, I had my WebSocket endpoint class packaged in a regular JAR file alongside other Enterprise JavaBeans, that was finally put in an EAR package. I figured that was a splendid design, but also one that made my endpoint totally undiscoverable. My EAR package already hosted a WAR module. So moving the endpoint into the WAR solved my problem.

Same page in the specification gives a hint why this must be:

The Java WebSocket implementation must use the web container scanning mechanism defined in [Servlet 3.0] to find annotated and programmatic endpoints contained within the WAR file at deployment time.

Further reading

The Java EE 7 Tutorial says:

When you deploy your application, the endpoint is available at ws://<host>:<port>/<application>/echo; for example, ws://localhost:8080/echoapp/echo.

Thus the tutorial does not touch the topic on packaging at all. Another Oracle article says:

In GlassFish, if your application is deployed with the contextroot mycontextroot in a Web container listening at port 8080 of localhost, the WebSocket will be accessible using ws://localhost:8080/mycontextroot/hello.

The word “if” in this quote might actually be interpreted as there is a free choice where we put our endpoint. At least that was what I read in when scanning through. I should emphasize that the Oracle article never said a word about any other container than a Web container (!). The JavaDoc of ServerContainer also, implicitly, state what we now know:

[blablabla..] during the deployment of the WAR file containing the endpoint.

The Enterprise Side of JavaFX: The Missing Part

The introduction you most likely don’t need

If you’re just a bit like me, you adore Java EE and all it has to offer. Java EE makes remoting from an application client a breeze if you stick to ordinary Java SE Swing based application clients, Java Web Start and dependency injection. Then all you have to do is to annotate a static field in your application client’s Main class and then go to work with this variable and everything just works.

But Java SE 7 update 6 happened which began the Oracle tradition of including JavaFX runtime libraries and utilities. Oracle also announced they will drop Swing in favor of JavaFX and indeed that is a good thing since Swing, which is today some kind of a standard for Java GUI:s, hasn’t been updated for a really long time and lost its competitive edge to other frameworks and languages. JavaFX on the other hand is new technology; featuring nice stuff like hardware acceleration and touch capabilities. I’m sure you can google the rest 😉

So what is the problem?

You cannot package a JavaFX client in an EAR package and then do dependency injection as if the application client is just another regular enterprise application client. Well, in theory I don’t think there’s anything there to stop you. I just haven’t got it to work in a straight forward way..

..until I found the solution I will present in this post/tutorial. The solution that will package a JavaFX application in an EAR package and then use resources from your Java EE application server with dependency injection.

You will not have to do any JNDI lookup programmatically and it even works with role based authentication as will be shown! All because your application client will for starters be a standard Java SE application that in his turn, when everything has been setup, starts a JavaFX application. The trick is not ugly, it is a pure JavaFX solution with kept benefits. Your ordinary thread will call javafx.application.Application#launch(Class, String) which will launch and setup the JavaFX application you’re used to. No strings attached! The solution is to be considered more of a packaging trick than anything else. If I haven’t made myself clear enough: The end GUI is a complete JavaFX application and nothing will be lost. You will even maintain your standard working model with separate FXML files for the structure of your GUI elements and controller classes in separate files that handle the business logic behind the GUI elements. You will not have to build scripts for Maven or Ant. You will not have to pass eye straining arguments to the Java- compiler or virtual machine. The solution will be completely built using only wizards from the NetBeans IDE and some minor code customizations.

Alternative solutions

One apparent way to connect a remote JavaFX desktop application with your application server is to use a HTTP wired web service. Oracle has demonstrated consuming a RESTful web service from a JavaFX application here, here and here. Oh yes, there are some “parts” here and here too. However, REST is not the only enterprise communication model out there, although as of today, it is the only remoting model you can found demonstrated on the Internet. For a particular project of mine, I found that JMS was a better alternative. I also needed remote access to an EJB. Alas invoking server side resources through JNDI proved to be error prone and a real hassle. But with Java Web Start and dependency injection, the user won’t even have to supply an IP and port that maps to the server.

What we will produce

In this tutorial, you will build a JavaFX application, packaged together with an EJB in an EAR package and have the application client launch through Java Web Start. Then the client shall login and get a role before he makes a remote call to a server side EJB. Here is a screenshot of the finished application:


JavaFX Application Client


If you really want to know: My setup is NetBeans IDE 7.3 and GlassFish (build 5). All running on Windows 8 x64. And one more thing before we begin; I use a tremendously simplified package naming scheme. I use only one package name shared across all my projects/modules for this tutorial. IRL, that practice is much discouraged.

What you will find in this tutorial and related pages:

  • Create a new Java EE Enterprise Application (page 2)
  • Create a shared library (page 3)
  • Create a new stateless Enterprise JavaBean (page 4)
  • Setup the role in GlassFish (page 5)
  • The JavaFX client template (page 6)
  • The Swing client (page 7)
  • Setup the Swing client (page 8)
  • Configure GlassFish (page 9)
  • Write some Java logic (page 10)
  • Build, deploy and run! (page 11)
.Create a new stateless Enterprise JavaBeanCreate a new stateless Enterprise JavaBeanCreate a new stateless Enterprise JavaBeanBuild, deploy and ru