Thursday, April 13, 2017

Stateful Session Beans

In this article we are going to discuss how to setup session beans and how to use them.

The server we have used here is WildFly 10.1.0.

We have used maven cargo which will automatically download and run the server.

The whole project is available here.

You can download the code and then go through the explanations.

Let's start with Stateful beans Interface:

package com.baeldung.ejb.stateful.beans;

import java.util.List;

import javax.ejb.Remote;

@Remote
public interface ItemStatefulRemote {

    void addItem(String itemName);

    List<String> getItemList();

}

The ```@Remote``` signifies that the bean is remote.

After that we implement the class.

package com.baeldung.ejb.stateful.beans;

import java.util.ArrayList;
import java.util.List;

import javax.ejb.Stateful;

@Stateful(name = "ItemStatefulRemote")
public class ItemStateful implements ItemStatefulRemote {

    private List<String> itemList;

    public ItemStateful() {
        itemList = new ArrayList<String>();
    }

    @Override
    public void addItem(String itemName) {
        itemList.add(itemName);
    }

    @Override
    public List<String> getItemList() {
        return itemList;
    }

}


@Stateful denotes that the bean is stateful bean. Once we are done with the coding part we will discuss in details the difference between a stateful and stateless bean.

We are done with the implementation of the beans. 

Now let's implement the client which will access these beans:

package com.baeldung.ejb.session.client;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import com.baeldung.ejb.stateful.beans.ItemStatefulRemote;

public class EJBStatefulClient {

 public EJBStatefulClient() {
 }

 private Context context = null;

 public Boolean getEJBRemoteMessage() {
  EJBStatefulClient ejb = new EJBStatefulClient();
  Boolean result = true;
  try {
   // 1. Obtaining Context
   ejb.createInitialContext();
   // 2. Generate JNDI Lookup name and caste
   ItemStatefulRemote itemStatefulOne = ejb.lookup();
   ItemStatefulRemote itemStatefulTwo = ejb.lookup();

   itemStatefulOne.addItem("Book");
   itemStatefulOne.addItem("Pen");
   itemStatefulOne.addItem("Copy");
   itemStatefulOne.addItem("Pencil");

   result = itemStatefulOne.getItemList().equals(itemStatefulTwo.getItemList());

   return result;
  } catch (NamingException e) {
   e.printStackTrace();
   return false;
  } finally {
   try {
    ejb.closeContext();
   } catch (NamingException e) {
    e.printStackTrace();

   }
  }
 }

 public ItemStatefulRemote lookup() throws NamingException {

  // The app name is the EAR name of the deployed EJB without .ear suffix.
  // Since we haven't deployed the application as a .ear, the app name for
  // us will be an empty string
  final String appName = "";
  final String moduleName = "session-beans";
  final String distinctName = "";
  final String beanName = "ItemStatefulRemote";
  final String viewClassName = ItemStatefulRemote.class.getName() + "?stateful";
  final String toLookup = String.format("ejb:%s/%s/%s/%s!%s", appName, moduleName, distinctName, beanName,
    viewClassName);
  return (ItemStatefulRemote) context.lookup(toLookup);
 }

 public void createInitialContext() throws NamingException {
  Properties prop = new Properties();
  prop.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
  prop.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
  prop.put(Context.PROVIDER_URL, "http-remoting://127.0.0.1:8080");
  prop.put(Context.SECURITY_PRINCIPAL, "testUser");
  prop.put(Context.SECURITY_CREDENTIALS, "admin1234!");
  prop.put("jboss.naming.client.ejb.context", false);

  context = new InitialContext(prop);
 }

 public void closeContext() throws NamingException {
  if (context != null) {
   context.close();
  }
 }

This is the most important part of the ejb.

The client first uses the jndi notation to connect to the bean and after that it tries to add an item and look it up.

Since this is a stateful bean, it won't retain variables across states. 

We can design some tests to test this behavior:

package com.baeldung.ejb.session.client.test;

import static org.junit.Assert.*;

import org.junit.Test;

import com.baeldung.ejb.session.client.EJBStatefulClient;

public class EJBStatefulClientTest {

 @Test
 public void EJBClientTest() {
  EJBStatefulClient ejbStatefulClient = new EJBStatefulClient();
  assertFalse(ejbStatefulClient.getEJBRemoteMessage());
 }

}

For the entire application, look at my GitHub code. I have a detailed page on how to run the examples.

If you have any questions feel free to email me at pritambanerjee999@gmail.com






    

No comments:

Post a Comment