> For the complete documentation index, see [llms.txt](https://abhishek-gupta.gitbook.io/java-websocket-api-handbook/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://abhishek-gupta.gitbook.io/java-websocket-api-handbook/part-1-tying_in_with_the_java_ee_platform.md).

# Part-1: Tying in with the Java EE Platform

The Java WebSocket API baked into the Java EE Platform (Java EE 7 and above). This chapter talks about other Java EE technologies which the WebSocket API integrates with. We will explore interoperability with the following Java EE specifications.

* Enterprise Java Beans (EJB)
* Context and Dependency Injection (CDI)

Before we dive in, please note that

> container managed injection features are **not** available to WebSocket endpoints which override the container implemented initialization (using the `ServerEndpointConfig.Configurator`)

## EJB integration

In this section, we'll look at how WebSocket endpoints can integrate with EJBs. The following aspects will be explored

* **Decorating** WebSocket endpoints with [Core EJB component model](https://abhirockzz.gitbooks.io/ejb-annotations-primer/content/EJB-Core.html) annotations
* [EJB based **Dependency Injection**](https://abhirockzz.gitbooks.io/ejb-annotations-primer/content/Dependency%20and%20Resource%20Injection.html) in WebSocket endpoints
* Using [EJB **Interceptors**](https://abhirockzz.gitbooks.io/ejb-annotations-primer/content/Aspect%20Oriented%20programming%20with%20Interceptors.html) in WebSocket endpoints

### Decorating WebSocket endpoints with EJB

> **Important**: Please note that support for EJB annotations on WebSocket endpoints is **not** a standard (specification mandated) feature

#### `@Singleton`

By default, the container creates a new WebSocket (server) endpoint instance per client. In case you need a single instance, you can implement this using a custom `ServerEndpointConfig.Configurator` (override the [`getEndpointInstance`](http://docs.oracle.com/javaee/7/api/javax/websocket/server/ServerEndpointConfig.Configurator.html#getEndpointInstance-java.lang.Class-) to be specific and return the same instance). As mentioned in the **Configuration** chapter, this means that you might have to sacrifice some of the (Java EE) platform related services like dependency injection

**Alternate solution** - A similar behavior can be achieved by decorating the WebSocket endpoint with `@Singleton`

```
@Singleton
@ServerEndpoint("/singleton/")
public class SingletonlEndpoint {

    @OnOpen
    public void onOpen(Session s) throws IOException {
        s.getBasicRemote().sendText(String.valueOf(hashCode()));
    }

    @PreDestroy
    public void onDestroy() {
        System.out.println("Singleton bean " + hashCode() + " will be destroyed");
    }

    @OnClose
    public void onClose(Session session, CloseReason closeReason) {
        System.out.println("Closed " + session.getId() + " due to " + closeReason.getCloseCode());
    }
}
```

**Concurrency semantics**

In case of a `@Singleton`, all the clients will interact with **one** server endpoint instance. Here is a quick summary of how the EJB as well as WebSocket threading semantics are applied

* The `Singleton` bean default approach ([WRITE lock](https://abhirockzz.gitbooks.io/ejb-annotations-primer/content/Concurrency.html#lock)) ensures single threaded access across all connected clients
* If thread-safety is not a concern (e.g. in case where you do not deal with client specific data/state in your logic) and you do not want the single-threaded access model to be a bottleneck, override the default behavior by switching to a [READ lock](https://abhirockzz.gitbooks.io/ejb-annotations-primer/content/Concurrency.html#lock) which allows concurrent threads to access the methods (*unless of course a WRITE lock is not already in effect*)

> The above mentioned semantics are with respect to ALL the WebSocket clients. From the point of view of a *single* client, the default strategy of one thread at a time, per endpoint instance per client continues to apply (more in the **Concurrency** chapter)

#### `@Stateful`

It's only possible to have one `@Stateful` EJB instance per WebSocket client - this is in tune with the default behavior outlined by the WebSocket specification. Things would get interesting from a state management perspective

* passivation capabilities of `Stateful` beans can be leveraged if needed (be careful about not storing references to non `java.io.Serializable` objects)
* EJB containers also support replication of Stateful beans across clusters which means that client state can be saved across multiple JVMs. With some custom logic (since `javax.websocket.Session` is not `Serializable`), it might be possible to implement a highly availabile (HA) setup for WebSocket applications

```
@Stateful
@ServerEndpoint("/chat/{user}")
public class StatefulChat {
    private transient Session s;
    private String userID;
    private List<History> history;

    @OnOpen
    public void onOpen(@PathParam("user") String user, Session s) throws IOException {
        this.userID= user;
        this.s = s;
    ....
    }

    @OnMessage
    public void chat(String msg) {
        history.add(msg);
       //route message to intended recipient(s)
    }
    ...
}
```

In the above example

* `userId` and (chat) `history` are user specific state which can be passivated, restored and replicated (across JVMs)
* `Session` is marked `transient` since we do not intend to serialize it to disk not over network (other JVMs in cluster)

#### `@Stateless`

Using `@Stateless` style endpoints can prove to be useful as well. Here are some of the noteworthy points

* Instance creation: A random instance is picked up from the [EJB pool](https://abhirockzz.gitbooks.io/ejb-annotations-primer/content/Pooling.html) (as per availability). It's possible to fine tune the pool in order to extract maximum performance (e.g. deploy time initilization if EJBs etc.) &#x20;
* Once allocated, the same bean instance is used throughtout the lifecycle of the `Session`  &#x20;

```
@Stateless
@ServerEndpoint("/stateless/")
public class StatelessEndpoint {

    @OnOpen
    public void onopen(Session s) throws IOException {
        s.getBasicRemote().sendText(String.valueOf(hashCode()));
    }

    //same logic as in @Singleton endpoint

}
```

### Dependency Injection

All EJB flavors (except `MessageDriven`) `Stateless`, `Stateful` and `Singleton` can be injected into WebSocket endpoints. A good strategy would be to implement core business logic using EJBs which can be then invoked from within WebSocket endpoint lifecycle (callback) methods

#### Injecting a `@Stateful` EJB

There is a one-to-one association between the WebSocket client & endpoint (which is by default) as well as the injected `Stateful` EJB instance, which makes it an ideal candidate for storing client specific state. It offers advanced semantics as compared to simple `java.util.Map` interface exposed by `getUserProperties` method in `javax.websocket.Session`)

```
@ServerEndpoint("/letschat/{login-id}")
public class ChatEndpoint {

    @EJB
    private ClientChatState ccs; //stateful EJB

    private String userID;

    @OnOpen
    public void connOpened(@PathParam("login-id") String loginID, Session session) {
        ccs.setUser(loginID)
           .currentState(State.JOINED); //everyone likes a fluent API!
    }

    @OnMessage
    public void onMessage(String msg, Session session) {
        ccs.lastReceivedMsg(msg);
    }

    @OnClose
    public void onClose(Session session) {
        ccs.dispose(); //method annotated with @Remove
    }
    ...
}
```

> **Tip**: Implement a [`@Remove` annotated method](https://abhirockzz.gitbooks.io/ejb-annotations-primer/content/Lifecycle%20Management.html#remove) in the `Stateful` EJB and call it from the `@OnClose` callback method. This will ensure that the EJB is removed from the memory immediately rather than depending upon [`@StatefulTimeout` configuration](https://abhirockzz.gitbooks.io/ejb-annotations-primer/content/Lifecycle%20Management.html#statefultimeout)

#### Injecting `@Stateless` and `@Singleton` EJBs

`@Stateless` and `@Singleton` EJBs can also be injected seamlessly. All the EJB features like transactions, simpler concurrency model, lifecycle management etc. can be leveraged

```
@ServerEndpoint("/chat/")
public class ChatEndpoint {

    @EJB
    private ChatHistory ch; //stateless EJB

    @EJB
    private ConnectedUsers users; //singleton EJB 

    @OnMessage
    public void onMessage(Session session){
        //business logic which makes use of the injected instances
    }
    ...
}
```

The table below summarizes the behavior when EJBs are injected into WebSocket endpoints

| Injected EJB type | Behavior                                     |
| ----------------- | -------------------------------------------- |
| `@Stateless`      | a random instance is picked up from the pool |
| `@Singleton`      | the same instance is injected                |
| `@Stateful`       | the bean is tied to the endpoint instance    |

> **beans.xml** (in WEB-INF) is required in order to leverage Dependency Injection support

### Interceptors

Just like EJB based injection support, Interceptor support in not officially supported by the WebSocket specification. You can implement cross-cutting business logic and then tie them to specific classes/methods using the `@Interceptors` [annotation](https://abhirockzz.gitbooks.io/ejb-annotations-primer/content/Aspect%20Oriented%20programming%20with%20Interceptors.html#interceptors). You should employ the annotation for the type of interceptor i.e. `@AroundInvoke`, `@AroundConstruct` etc.

```
public class LoggingInerceptor {

    @AroundInvoke
    public Object log(InvocationContext ic) throws Exception {
        Object retVal = null;

        try {
            Logger.getAnonymousLogger().entering(ic.getTarget().getClass().getSimpleName(), 
                                                 ic.getMethod().getName());

            retVal = ic.proceed(); //allow intercepted method to be invoked

        } catch (Exception e) {
            Logger.getAnonymousLogger().severe(e.getMessage());
        } finally {
            Logger.getAnonymousLogger().exiting(ic.getTarget().getClass().getSimpleName(),
                                                ic.getMethod().getName());
        }

        return retVal;
    }
}
```

Apply the interceptor

```
@ServerEndpoint("/chat/")
public class ChatEndpoint {

    @Interceptors(LoggingInteceptor.class)
    @OnMessage
    public void onMessage(Session session){
        //business logic
    }
    ...
}
```

## CDI integration

Although CDI integration offers features similar to that of the EJB ones i.e. *Dependency Injection* and *Interceptors*, it's worth noting that these are officialy supported by the specification (**Section 7.1.1**)

### Dependency Injection

As part of the the DI support, `@javax.inject.Inject` can be used (on constructor, method, field) to inject CDI managed beans

```
@RequestScoped //CDI annotation
public class CDIManagedBean {
    ....
}
```

```
@ServerEndpoint("/stocks/")
public class StockTracker {

    @Inject
    private CDIManagedBean cdiBean;

    @OnOpen
    public void onOpenCallback(Session s){
        cdiBean.doSomething(); //use injected instance
    }
}
```

```
@ServerEndpoint("/weather/")
@Stateless // works with an EJB as well
public class WeatherTracker {

    @Inject
    private CDIManagedBean cdiBean;

    @OnOpen
    public void onOpenCallback(Session s){
        cdiBean.doSomething(); //use injected instance
    }
}
```

### Interceptors

CDI Interceptors introduce an additional layer of abstraction. Let's look at a simple example

First up, we need to define an *Interceptor binding*

```
//the interceptor binding

@Inherited
@InterceptorBinding
@Retention(RUNTIME)
@Target({METHOD, TYPE})
public @interface LoggingInterceptorBinding {}
```

Implement our interceptor and bind it

```
//The interceptor implementation - notice the usage of additional annotations as compared to the EJB interceptors

@Interceptor
@LoggingInterceptorBinding
public class CDIBasedLoggingInterceptor {

    //implementation is the same (as in the case of EJB based interceptor)
    @AroundInvoke
    public Object log(InvocationContext ic) throws Exception {
        Object retVal = null;

        try {
            Logger.getAnonymousLogger().entering(ic.getTarget().getClass().getSimpleName(), 
                                                 ic.getMethod().getName());

            retVal = ic.proceed(); //allow intercepted method to be invoked

        } catch (Exception e) {
            Logger.getAnonymousLogger().severe(e.getMessage());
        } finally {
            Logger.getAnonymousLogger().exiting(ic.getTarget().getClass().getSimpleName(),
                                                ic.getMethod().getName());
        }

        return retVal;
    }
}
```

Apply the interceptor where needed (via the binding)

```
@ServerEndpoint("/chat/")
public class ChatEndpoint {

    @LoggingInterceptorBinding //binding the CDIBasedLoggingInterceptor
    @OnMessage
    public void onChatMsgRecieved(String chatMsg) {
        //....
    }
}
```

Oh, and don't forget to specify the interceptor in **beans.xml** (compulsory)

```
//Interceptors need to be defind in beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
bean-discovery-mode="all">
    <interceptors>
        <class>com.wordpress.abhirockzz.jaws.handbook.CDIBasedLoggingInterceptor</class>
    </interceptors>
</beans>
```

> The CDI based interceptor works for EJB based WebSocket endpoints as well

## Summary

Here is a quick review of what's supported for WebSocket in terms of CDI and EJB integration. Everything works.. Awesome!

| Feature                    | Supported in EJB Annotated WebSocket Endpoint ? | Supported in Plain WebSocket endpoint ? |
| -------------------------- | ----------------------------------------------- | --------------------------------------- |
| Inject CDI managed beans   | yes                                             | yes                                     |
| Inject EJBs with `@Inject` | yes                                             | yes                                     |
| Inject EJBs with `@EJB`    | yes                                             | yes                                     |
| Use CDI interceptors       | yes                                             | yes                                     |
| Use EJB interceptors       | yes                                             | yes                                     |

## Coming up

This concludes part I of this chapter. The second (and final) part will cover **Servlet** and **Security** related integration points
