# 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


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://abhishek-gupta.gitbook.io/java-websocket-api-handbook/part-1-tying_in_with_the_java_ee_platform.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
