Welcome!

Weblogic Authors: Yeshim Deniz, Elizabeth White, Michael Meiner, Michael Bushong, Avi Rosenthal

Related Topics: Weblogic

Weblogic: Article

Shared Sessions Using EJBs

Shared Sessions Using EJBs

The Problem:
We have a J2EE application where clients with the same userid need to share the session data that is maintained on the server side. In addition, clients aren't just Web clients, but applets and applications as well. How should we implement that?

The Solution:
This is a typical problem when writing J2EE applications, since the J2EE APIs don't provide an out-of-the-box solution for this.

The Servlet API typically used with Web clients provides nice ways to manipulate the client's session and the data related to it, but doesn't offer a direct means of sharing the session data between clients (for security reasons). It's also somewhat limited to Web clients only.

Enterprise Java Beans (EJBs), on the other hand, could be used to implement this quite easily, since they work with any type of Java clients. It may be a bit heavyweight, but programmatically it's quite straightforward, so let's take a closer look at it.

A stateless Session EJB easily comes to mind, since it enables the client's state on the server-side. Session EJBs (or instances of them) are also sharable between client sessions by passing the reference to them (or actually into their remote interface) within the application, like a servlet. In order to pass references between sessions, the application needs to explicitly maintain a look-up table of the references for each client identified, so it knows to relate the user (along with userid) with the proper instance of a Session EJB when that already exists.

However, that's pretty much what WLS does when Entity EJBs are used - or at least there is a lot of similarity in this scenario. It keeps the reference to each Entity EJB instantiated in the memory and then passes it (or the reference to the EJB's Remote Interface of it) to the client, which requests it via the bean's findByPrimaryKey method of the Home Interface. If the Entity EJB is not found since it does not yet exist, it can be created on the fly to be related with the client and its session the first time the client logs in. Therefore, Entity EJB instances are easily shared, even between clients not running in the same JVM.

Note: an Entity EJB instance does not always refer to a row in the database; it can be totally virtual. But since Entity Beans are especially good at accessing persistent data, it gives us a chance to provide persistency for our sessions (and the data in them) in case of application crashes, etc.

To locate the session references for clients, use of the findByPrimaryKey method is logical, since the primary key is actually the client's userid for the application. The only thing that's left for the application to do is the appropriate authentication of clients, before they can access the session data via the bean's findByPrimaryKey method.

Creating the Sample Application
Now we're going to design the sample application. First, we divide the application into four parts:

1.   UserSession: Class containing the user's session data in Hashtable plus some other information like the user's userId. It utilizes the Serializer class for session data persistency (see below). UserSession class can be used locally at first, and then remotely via the Entity EJB "wrapper" to be easily shared with multiple clients of many types (JSP and Java clients, etc.).

2.   UserSessionSerializer: Class for session data persistency. Java serialization is used instead of JDBC in the first step to keep this as simple as possible. Later on, we can replace this with pool-oriented JDBC-based persistency for distributed larger-scale applications. There's always one file on the disk per session - even if it's shared by multiple clients -and an EJB instance accessing it.

3)   EJB wrapper: For distributed UserSession objects. It's subclassed from the UserSession. As an Entity EJB, it consists of three separate classes in the sharedSessionSample.remote package (others are stored in the package "local").

4)   Sample JSP client using SessionData objects, first locally and then remotely

Next, we create a package named sharedSession-Sample.local, and place two classes, the UserSession class and the UserSessionSerializer class, in it. The UserSession class has three class members (variables) and methods:

Members:

protected String path;
protected String userId;
protected Hashtable sessionData;
Methods (the throw definitions are not shown):

public void create(String userId)
public void load(String userId)
public void save()
public void remove()
public Object getValue(String name)
public void setValue(String name, Object object)
public void removeValue(String name)
public Hashtable getValues()
public void setValues(Hashtable values)
The class member path defines the directory where the serialized sessions are stored on the disk and loaded from. Typically, the path is the same for all sessions. The userId defines the owner of the session and is used to name the file when serialized (that is, a session of the user "John" will be serialized as a file named "John.session" onto the disk into the specified directory). The Hashtable sessionData holds the session named values. Note: we don't actually store the whole UserSession when serialized, just the sessionData member object.

Getters and Setters
Methods are constructed so they can easily be extended to work as an Entity EJB. The create() method is used to create a new, empty session, which can be saved by save() method after one or more values have been set to the session via the setters setValue() or setValues(). The difference between these setters is obvious: the first one sets one named value at the time, whereas the latter sets all the values for the session (passed as a Hashtable). It is the same with getters getValue() and getValues(). The method load() is used to load an existing session and its data from the disk, and throws an exception if not found (in that case it should probably be created), as opposed to the method create(), which throws an exception when the session already exists.

The setters do not save() automatically; one has to be called explicitly by the client. However, that's implemented to the Entity EJB.

One thing to note is that the UserSession is implemented in such a way that getValues() and setValues() work "by value" instead of "by reference." It's the preferred approach here, to avoid unintentional changes to the session data on JSPs (I've seen it happen many times with objects like a Hashtable). The actual code is shown in Listing 1 (the code for this article may be found online at www.sys-con.com/weblogic/sourcec.cfm.

The methods create(), load(), and save() use the SessionSerializer class, which has no member variables, just static methods:

public static void serialize(String path, String userId,
Hashtable sessionData)
public static Hashtable deserialize(String path, String userId)
public static void remove(String path, String userId)
The serialize() method is used to save (using Java serialization) the Hashtable containing the named session values onto the disk. Deserialize() is the opposite to serialize() in order to instantiate the Hashtable object from existing session values on the disk. The remove() method can delete serialized session values from the disk.

Shown below are examples of the implementation of SessionSerializer's serialize() method and the UserSession's save() method to show how the use of the SessionSerializer has been implemented.

The SessionSerializer's serialize method:

public static void serialize(String path,
String userId,
Hashtable sessionData) throws Exception
{
FileOutputStream ostream =
new FileOutputStream(path + "/" + userId + ".session");
ObjectOutputStream p = new ObjectOutputStream(ostream);
p.writeObject(sessionData);
ostream.close();
}
The UserSession's save() method:

// Note that the path needs to be set first,
before calling save
public void save() throws Exception
{
UserSessionSerializer.serialize(path, userId,
sessionData);
}
Next, the files are compiled into Java classes. Once we get the WLS running and these files copied into the classpath, the sample JSP page can be created to test accessing session values locally (that is, within the same JVM) as the first part of the sample. It uses the setValue() method for incrementing an integer value "i" for the user; if a user isn't specified in the HTTP request it is considered to be "JohnDoe." There's no authentication, which in real life would be needed (the standard Web app definition can be used; see Listing 2).

Alternatively, the method setValues() (instead of setValue()) can be used to increment the value for "i" as shown below:

int i = 0;
Hashtable values = userSession.getValues();
if(values.get("i") != null)
{
i = ((Integer) values.get("i")).intValue();
i++;
}
values.put("i", new Integer(i));
userSession.setValues(values);
Conversion
Now that the classes for accessing the session values locally have been implemented and tested, they're prepared for remote use by both local and remote clients by being converted into an Entity EJB. That also enables easy sharing of the session data between clients, since the Entity EJB takes care of synchronization between client method calls. In addition, using bean-managed persistence (BMP) and Java serialization, we're able to serialize any named values in the Hashtable without having to worry about JDBC datatypes and so on in our EJB.

However, normal rules apply when writing (updating) the same session values from two or more clients simultaneously; there's no way that the EJB could prevent overwriting of data in those cases. For that reason, make sure to add an identifier (e.g., a transaction id or timestamp from the file system, etc.) that's sent between the client and the server to indicate if the session data has been updated elsewhere (another client) when doing updates from multiple clients to the same session and its data.

In order to enable the local.UserSession for remote use, three EJB classes are implemented:

  • UserSessionHome: the home interface of the entity EJB
  • UserSession: the remote interface of the entity EJB
  • UserSessionBean: the bean implementation class that is subclassed from the UserSession of the local package

    All classes are placed in a package named sharedSessionSample.remote to differentiate them from the local classes (partly with same name).

    The UserSessionHome interface defines two methods to create new and locate existing sessions remotely:

    public UserSession create(String userId)
    public UserSession findByPrimaryKey(String userId)
    Since the UserSessionBean (which we'll see in a minute) is subclassed from the local.UserSession, the remote.UserSession remote interface is used to publish the methods of the local.UserSession for remote use (the throw definitions are not shown):

    public Object getValue(String name)
    public void setValue(String name, Object object)
    public void removeValue(String name)
    public Hashtable getValues()
    public void setValues(Hashtable values)
    The EJB implementation class remote. User-SessionBean has only one member variable - along with those that are inherited from the local. UserSession class - and the following methods:

    Members:

    private transient EntityContext ctx;
    Methods (some standard EJB methods and throw definitions are not shown):

    public String ejbCreate(String userId)

    public String ejbFindByPrimaryKey(String userId)
    public void ejbLoad()
    public void ejbStore()
    public void ejbRemove()
    protected void setPath()

    The ejbCreate() method is used to create a new session data object in case it doesn't exist yet. This object is created by calling the create() method of itself inherited from the local.User-Session class. If the creation succeeds (that is, no session exists already with the given userId), the userId is returned and the EJB is instantiated by the WLS for shared and remote use. If the session already exists, a standard DuplicateKeyException is thrown (see Listing 3).

    The setPath() method is used to read the serialization directory path from EJBs' properties and is implemented as follows:

    try
    {
    InitialContext ic = new InitialContext();
    setPath((String)
    ic.lookup("java:/comp/env/storagePath"));

    }
    catch (NamingException ne)
    {
    // defaults to '/sessions' directory under WebLogic
    // root dir, if not defined. For clustering, use a shared dir.
    setPath("./sessions");
    }

    Note that in the case of clustering, which is a nice feature of WebLogic and especially typical of high load sites, the directory path should be a shared resource for all application server instances - otherwise, the clustering wouldn't work properly.

    Load and Store Methods
    The opposite of ejbCreate(), the findByPrimaryKey() is used to locate an existing session on the server. First, the method tries to find a serialized session on the disk by calling its own load() method, inherited from the local.UserSession class, and throws ObjectNotFoundException if it is not found. However, if the session is found (the load() succeeds), it returns the userId, from which the server knows to instantiate the EJB by calling the ejbLoad() method implicitly, resulting in the loading of the actual session data from the disk (see Listing 4).

    The same load() method is used for two purposes: first, for trying to locate an existing session from the disk when doing the findByPrimary-Key(), and then for loading (deserializing) the actual data when the EJB is instantiated by the server (the ejbLoad() method). This may not be the best practice, but it works (We could have a separate find method instead, but to limit the size of the code we omit that).

    The ejbStore() method is called automatically by the server when any setter of the EJB is called. Therefore, there's no need for an explicit save() method in the EJB. We could easily add it for optimization reasons later on, but it's hardly needed here. Thus, the ejbStore() method is as follows:

    try
    {
    save();
    }
    catch(Exception e)
    {
    throw new EJBException(e.toString());
    }
    Finally, the ejbRemove() method, which can be used to delete existing session data:

    try
    {
    remove();
    }
    catch(Exception e)
    {
    throw new EJBException(e.toString());
    }
    Now that the EJB is ready, it's time to modify the JSP for using the EJB instead of the local class. In Listing 5, the UserSession is accessed remotely to do basically the same increment as in Listing 2, but now it enables the client (a standalone Java application, for example) to run in a separate JVM from the server.

    In order to set more than one value at a time, the setValues() method can be used, as in this example of incrementing:

    int i = 0;
    Hashtable values =
    userSession.getValues();
    if(values.get("i") != null)
    {
    i = ((Integer)
    values.get("i")).intValue();
    i++;
    }
    values.put("i", new Integer(i));

    // Put other values as well and finally set them
    userSession.setValues(values);

    For optimization, the JNDI lookup for the EJB could be done only once and stored in the WebLogic Server's memory with application scope (see Listing 6).

    In addition, we could also cache the UserSession object itself to the user's HTTP session once found, in order to avoid subsequent findByPrimaryKey() calls in case of JSP. Of course, for Java clients like applets, the caching isn't needed (used as a local object). The code for caching is shown in Listing 7.

  • More Stories By Mika Rinne

    Mika Rinne is a senior consultant with BEA Systems Inc. He has been programming since he was 13 and in 1995 built an Internet and BEA
    TUXEDO-based online ticket-selling service, the first of its kind in Scandinavia.

    Comments (1) View Comments

    Share your thoughts on this story.

    Add your comment
    You must be signed in to add a comment. Sign-in | Register

    In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.


    Most Recent Comments
    Davide Parisi 02/06/08 04:01:22 AM EST

    It's an helpful tips, but the code it's not complete, can we publish the entire source?

    @ThingsExpo Stories
    SYS-CON Events announced today that CAST Software will exhibit at SYS-CON's 21st International Cloud Expo®, which will take place on Oct 31 - Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. CAST was founded more than 25 years ago to make the invisible visible. Built around the idea that even the best analytics on the market still leave blind spots for technical teams looking to deliver better software and prevent outages, CAST provides the software intelligence that matter ...
    SYS-CON Events announced today that Daiya Industry will exhibit at the Japanese Pavilion at SYS-CON's 21st International Cloud Expo®, which will take place on Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. Ruby Development Inc. builds new services in short period of time and provides a continuous support of those services based on Ruby on Rails. For more information, please visit https://github.com/RubyDevInc.
    As businesses evolve, they need technology that is simple to help them succeed today and flexible enough to help them build for tomorrow. Chrome is fit for the workplace of the future — providing a secure, consistent user experience across a range of devices that can be used anywhere. In her session at 21st Cloud Expo, Vidya Nagarajan, a Senior Product Manager at Google, will take a look at various options as to how ChromeOS can be leveraged to interact with people on the devices, and formats th...
    SYS-CON Events announced today that Yuasa System will exhibit at the Japan External Trade Organization (JETRO) Pavilion at SYS-CON's 21st International Cloud Expo®, which will take place on Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. Yuasa System is introducing a multi-purpose endurance testing system for flexible displays, OLED devices, flexible substrates, flat cables, and films in smartphones, wearables, automobiles, and healthcare.
    SYS-CON Events announced today that Taica will exhibit at the Japan External Trade Organization (JETRO) Pavilion at SYS-CON's 21st International Cloud Expo®, which will take place on Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. Taica manufacturers Alpha-GEL brand silicone components and materials, which maintain outstanding performance over a wide temperature range -40C to +200C. For more information, visit http://www.taica.co.jp/english/.
    SYS-CON Events announced today that SourceForge has been named “Media Sponsor” of SYS-CON's 21st International Cloud Expo, which will take place on Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. SourceForge is the largest, most trusted destination for Open Source Software development, collaboration, discovery and download on the web serving over 32 million viewers, 150 million downloads and over 460,000 active development projects each and every month.
    SYS-CON Events announced today that Nihon Micron will exhibit at the Japan External Trade Organization (JETRO) Pavilion at SYS-CON's 21st International Cloud Expo®, which will take place on Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. Nihon Micron Co., Ltd. strives for technological innovation to establish high-density, high-precision processing technology for providing printed circuit board and metal mount RFID tags used for communication devices. For more inf...
    Enterprises have taken advantage of IoT to achieve important revenue and cost advantages. What is less apparent is how incumbent enterprises operating at scale have, following success with IoT, built analytic, operations management and software development capabilities – ranging from autonomous vehicles to manageable robotics installations. They have embraced these capabilities as if they were Silicon Valley startups. As a result, many firms employ new business models that place enormous impor...
    SYS-CON Events announced today that MIRAI Inc. will exhibit at the Japan External Trade Organization (JETRO) Pavilion at SYS-CON's 21st International Cloud Expo®, which will take place on Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. MIRAI Inc. are IT consultants from the public sector whose mission is to solve social issues by technology and innovation and to create a meaningful future for people.
    Widespread fragmentation is stalling the growth of the IIoT and making it difficult for partners to work together. The number of software platforms, apps, hardware and connectivity standards is creating paralysis among businesses that are afraid of being locked into a solution. EdgeX Foundry is unifying the community around a common IoT edge framework and an ecosystem of interoperable components.
    SYS-CON Events announced today that Dasher Technologies will exhibit at SYS-CON's 21st International Cloud Expo®, which will take place on Oct 31 - Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. Dasher Technologies, Inc. ® is a premier IT solution provider that delivers expert technical resources along with trusted account executives to architect and deliver complete IT solutions and services to help our clients execute their goals, plans and objectives. Since 1999, we'v...
    SYS-CON Events announced today that TidalScale, a leading provider of systems and services, will exhibit at SYS-CON's 21st International Cloud Expo®, which will take place on Oct 31 - Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. TidalScale has been involved in shaping the computing landscape. They've designed, developed and deployed some of the most important and successful systems and services in the history of the computing industry - internet, Ethernet, operating s...
    SYS-CON Events announced today that Massive Networks, that helps your business operate seamlessly with fast, reliable, and secure internet and network solutions, has been named "Exhibitor" of SYS-CON's 21st International Cloud Expo ®, which will take place on Oct 31 - Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. As a premier telecommunications provider, Massive Networks is headquartered out of Louisville, Colorado. With years of experience under their belt, their team of...
    SYS-CON Events announced today that IBM has been named “Diamond Sponsor” of SYS-CON's 21st Cloud Expo, which will take place on October 31 through November 2nd 2017 at the Santa Clara Convention Center in Santa Clara, California.
    Infoblox delivers Actionable Network Intelligence to enterprise, government, and service provider customers around the world. They are the industry leader in DNS, DHCP, and IP address management, the category known as DDI. We empower thousands of organizations to control and secure their networks from the core-enabling them to increase efficiency and visibility, improve customer service, and meet compliance requirements.
    SYS-CON Events announced today that TidalScale will exhibit at SYS-CON's 21st International Cloud Expo®, which will take place on Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. TidalScale is the leading provider of Software-Defined Servers that bring flexibility to modern data centers by right-sizing servers on the fly to fit any data set or workload. TidalScale’s award-winning inverse hypervisor technology combines multiple commodity servers (including their ass...
    As hybrid cloud becomes the de-facto standard mode of operation for most enterprises, new challenges arise on how to efficiently and economically share data across environments. In his session at 21st Cloud Expo, Dr. Allon Cohen, VP of Product at Elastifile, will explore new techniques and best practices that help enterprise IT benefit from the advantages of hybrid cloud environments by enabling data availability for both legacy enterprise and cloud-native mission critical applications. By rev...
    Join IBM November 1 at 21st Cloud Expo at the Santa Clara Convention Center in Santa Clara, CA, and learn how IBM Watson can bring cognitive services and AI to intelligent, unmanned systems. Cognitive analysis impacts today’s systems with unparalleled ability that were previously available only to manned, back-end operations. Thanks to cloud processing, IBM Watson can bring cognitive services and AI to intelligent, unmanned systems. Imagine a robot vacuum that becomes your personal assistant tha...
    As popularity of the smart home is growing and continues to go mainstream, technological factors play a greater role. The IoT protocol houses the interoperability battery consumption, security, and configuration of a smart home device, and it can be difficult for companies to choose the right kind for their product. For both DIY and professionally installed smart homes, developers need to consider each of these elements for their product to be successful in the market and current smart homes.
    In his Opening Keynote at 21st Cloud Expo, John Considine, General Manager of IBM Cloud Infrastructure, will lead you through the exciting evolution of the cloud. He'll look at this major disruption from the perspective of technology, business models, and what this means for enterprises of all sizes. John Considine is General Manager of Cloud Infrastructure Services at IBM. In that role he is responsible for leading IBM’s public cloud infrastructure including strategy, development, and offering ...