Programmer's Guide



Chapter 19   Using EJBs with SilverStream Applications

This chapter describes SilverStream support for Enterprise JavaBeans. It covers the following topics:

This chapter assumes that you are somewhat familiar with EJBs. If you are new to EJBs or just want to explore a specific EJB topic, you can find more information with the following resources:

Resource

Description

The EJB Specification Version 1.1

The complete specification for the EJB component model.

    Available on the Sun Java Web site: http://java.sun.com/products/ejb/docs.html

The EJB Learning Center

An index to EJB learning and reference materials from Sun, with links to many documents and Web sites.

    Available on the Sun Java Web site: http://java.sun.com/products/ejb/training.html

SilverStream EJB support   Top of page

The Enterprise JavaBeans Specification provides a framework that allows you to build reusable Java-based components that are remotely accessible, transactional, and secure. SilverStream includes a complete EJB implementation that is compatible with the EJB1.1 (Moscone) Specification. The SilverStream implementation includes support for the following:

Integrated tools for designing, customizing, assembling, and administering EJBs   Top of page

SilverStream provides an integrated IDE that you can use to design and customize EJBs. It also provides the ability to deploy EJBs designed using other IDEs. The SilverStream SMC provides complete access to the runtime environment so that you can administer deployed EJBs. See the section on Writing EJB applications for information about SilverStream's EJB development and deployment tools.

    For more information on the SMC, see the Administrator's Guide.

Load balancing   Top of page

You can use SilverStream's standard clustering mechanisms with EJBs. SilverStream load-balancing is per-session. All EJBs used within a single session reside on one server within the cluster. Load balancing is transparent to the user; the client can do a normal JNDI lookup; the naming server handles the selection of the server on which to run the bean. As with other SilverStream components, failover is the responsibility of the application developer.

When using EJBs within a cluster, you must start your servers on different name service ports. The default name service port is 54890. You can configure the name service port using the SMC.

    For more information on SilverStream clustering mechanisms, see the Administrator's Guide.

Naming service   Top of page

SilverStream uses the Java Naming and Directory Interface (JNDI). SilverStream registers EJBs in the root context. If you specify a hierarchical naming structure for the bean's JNDI name in the deployment plan, SilverStream creates any intermediate subcontexts that do not already exist.

By default, SilverStream registers bean references, environment variables, and resource references in the java:comp/env context. You can follow the recommendations of the EJB specification and store the objects in a separate subcontext as described in the following table. SilverStream does not enforce these naming conventions so you can use the naming conventions that work best in your own production environment.As with bean JNDI names, SilverStream creates any intermediate contexts that do not already exist.

Type

Context

Bean references

java:comp/env/ejb/beanreference

Environment variables

java:comp/env/env_name

Resource references

java:comp/env/jdbc/resourcename

CAUTION!   Do not use duplicate JNDI names. If you do use duplicate JNDI names SilverStream does not generate a warning message; it simply overwrites an existing registered object with a newer one. When you attempt to access an object with the duplicate name, you will get the newer one which can cause unexpected behavior or errors.

SilverStream stores UserTransaction objects in this JNDI context name:

   "RMI/SilverStream-UserTransaction"

For more information, see the section on Transaction support.

Remote access   Top of page

SilverStream supports access to EJBs via RMI/IIOP using the JBroker Object Request Broker (ORB). JBroker is an enterprise-class Java-based CORBA ORB. It provides many important features for remote access.

    For more information on JBroker, see the documentation included in the Jbroker subdirectory of the SilverStream installation directory.

You can access an Enterprise JavaBean deployed on a SilverStream Server from any of the following:

Security   Top of page

EJBs deployed on a SilverStream Server are fully integrated with the SilverStream security model. The SilverStream container manages security at runtime using:

The SilverStream Server provides the following tools to specify and manage security for EJBs:

    For more information on mapping roles to principals, see Deploying EJBs.

Transaction support   Top of page

SilverStream provides transaction support within a single database. It does not support distributed transactions.

SilverStream supports user transactions via the javax.transaction.UserTransaction interface. A UserTransaction object can be obtained for SilverStream pages, JSPs, Java clients and session beans. To support SilverStream pages, JSPs, and Java clients, SilverStream binds the UserTransaction to the JNDI name "RMI/SilverStream-UserTransaction". For session beans the UserTransaction is available as part of the bean environment context or as a method on the javax.ejb.SessionContext.

Accessing a UserTransaction object from a SilverStream page or JSP

To access a UserTransaction object from a SilverStream page, use the initialContext.lookup() method as shown here making sure to narrow the object to the appropriate type:

    utx = (UserTransaction) PortableRemoteObject.narrow(initialContext.lookup("RMI/SilverStream-UserTransaction"), UserTransaction.class);

Accessing a UserTransaction object from a Java client

To access a UserTransaction object from a SilverStream form or other external Java client, you must use this syntax:

     sssw://host[:port]/RMI/SilverStream-UserTransaction

For example:

     utx = (UserTransaction) PortableRemoteObject.narrow(initialContext.lookup("sssw://host[:port]RMI/SilverStream-UserTransaction"), UserTransaction.class);

For external clients, you must already have a session established on the specified server.

For more information, see the chapter on "Writing External Java Clients" section of the Programmer’s Guide.

Accessing a UserTransaction object from a session bean

To access a UserTransaction object from a session bean (with bean-managed transaction demarcation), you can call the getUserTransaction() method. The environment is passed to the bean on the session context. In this example, the m_context is a javax.ejb.SessionContext and utx is a UserTransaction.

     utx = m_context.getUserTransaction(); 

As an alternative, you can get the UserTransaction from the java:comp Environment context like this:

     initialContext = new InitialContext();
          context = (Context) initialContext.lookup("java:comp/UserTransaction");

Writing EJB applications   Top of page

The following list describes the tasks associated with building an Enterprise JavaBean application along with the appropriate SilverStream tool.

  1. Write the Enterprise JavaBean classes and the home and remote interfaces.

    You can use SilverStream's Business Object Designer to create the EJB classes and interfaces. Alternatively, you can use an external IDE to develop your EJB application components.

  2. Package the beans and the interfaces in an EJB JAR file which must include an XML-based deployment descriptor.

    You can use SilverStream's JAR Designer to create and populate an EJB JAR and to create the required deployment descriptor. Alternatively, you can build the EJB JAR and deployment descriptor using an external tool and import it into the server using the JAR Designer's upload option, or the SilverCmd ImportMedia utility.

  3. Assemble the beans, from one or more EJB JARs, into an application.

    Once you have imported the EJB JAR to the server, you can use SilverStream's JAR Designer to modify the deployment descriptor and to combine the contents of one or more EJB JARs.

  4. Deploy the EJB JAR on an EJB-compliant server.

    You can use SilverStream's Deployment Plan Designer to deploy the EJB JAR on the SilverStream Server if you prefer a GUI environment. Alternatively, you can define the required deployment information in an XML file which you use with the SilverCmd DeployEJB utility.

What happens when you deploy an EJB JAR

When you deploy an EJB JAR, the SilverStream container uses the deployment descriptor, the deployment plan, and the contents of the EJB JAR to create implementation classes for the home and remote interfaces. It also generates wrappers that handle security and transactions. These wrappers ensure that the container provides the appropriate behavior for the bean.

The SilverStream container puts implementation classes into a remote JAR which is used by the bean's clients. It also generates a deployed object which contains the implementation classes used by the SilverStream server.

Writing portable beans   Top of page

To write completely portable beans (EJB 1.1), use only the following APIs:

You can also take advantage of EJB features like:

Using environment properties

A single EJB can be assembled into one or more applications, and can be deployed in one or more target environments. For this reason, the EJB specification allows you to refer to resources in the target environment in a way that can be customized later on. The EJB specification allows for this flexibility using environment properties for the following:

    For information about mapping these values at deployment time, Deploying EJBs

    For information about retrieving these values at runtime, see the EJB section of the online Application Techniques.

Using EJB's built-in transaction support

An important feature of EJB's transaction support is the ability to allow the Container to manage transactions for a bean. This is known as a container-managed or container-demarcated transaction. Container-demarcated transactions are declarative, that is, you define how each method participates in a transaction by setting a transaction attribute in the deployment descriptor. The container can then use the information in the deployment descriptor to provide the appropriate transactional behavior for the EJB.

Entity bean transactions are always container-demarcated. Session bean transactions can be container-demarcated or bean-demarcated (that is, managed by the bean itself). You can specify the management type in the deployment descriptor.

Beans using container-demarcated transactions can specify how the container manages the way each method participates in the transaction. SilverStream uses the Supported attribute as the default.

    For more information on setting the transaction management type, see Understanding Deployment Descriptors.

Container-managed transactions use the Java Transaction API (in the javax.transaction package). Session beans, using bean-managed transactions, can use the Java Transaction API, or the transaction API on a local resource, such as a database connection (using JDBC).

Using EJB's built-in security

A primary goal of EJB's security architecture is to allow portability of EJBs across servers with different security implementations. As with transactions, it achieves this goal by allowing the bean provider and application assembler to specify security requirements declaratively in the deployment descriptor. At deployment time, the deployer can map the security specifications to actual objects in the operational environment.

How security works

In EJBs, you specify security using security roles and method permissions. A security role is a way to group a set of users that need access to the same method or set of methods. A security role, as specified by the bean provider or application assembler, is not necessarily the same as a user or group in any target environment. It is more of an abstraction that can later be mapped to actual principals (users or groups).

Once you specify a set of security roles, you can specify which roles have execute permissions to a method or set of methods. When a client calls a method on the bean's home or remote interfaces, the container authenticates the user and checks the set of permissions. If the user is not allowed access to that method, the container throws an Exception.

You can create multiple security roles with permission to a number of methods. Methods can be accessed by different security roles. At runtime, the container checks the security of the caller against the deployment descriptor, to ensure that they are able to make the method call.

In SilverStream's implementation, if you secure at least one method, you must secure all methods or the container assumes all methods with unspecified security are restricted and cannot be called by any user, and it throws an AccessRightsViolation exception. Alternatively, you can choose not to secure any methods. This is a non-secure mode. SilverStream's sample applications run in non-secure mode.

Caller propagation

When you call an EJB residing on a SilverStream Server, SilverStream authenticates the user and uses the caller's identity for the duration of the caller's session on that server. All method calls run with the identity of that session. This can be slightly different for calls to beans residing on other SilverStream Servers.

For example, suppose that BeanA on Server1 calls BeanB on Server2. BeanB will run as the user that established the session on Server2. This might be a different user than BeanA depending on how the session was established.

Using SilverStream extensions   Top of page

You can use AgaDatas and can access other server resources if you intend to deploy your EJBs on the SilverStream Server.

Using AgaDatas

SilverStream's primary data access mechanism for server-side objects is the AgaData. An AgaData, like any component of the SilverStream data cache layer implements the AgiRowCursor and AgiRowSetManager interfaces. This means that the data can be traversed and can be added, changed, or removed from the target data store.

A primary benefit to using AgaDatas is the simpler data access API; however, the main drawback is that EJB's using AgaDatas are not portable to non-SilverStream EJB-compliant servers.

What you need to do

An AgaData that provides data for an EJB must be bound to a SilverStream data source object (DSO). Here is what you need to do within the bean:

  1. Instantiate an AgaData.

  2. Initialize the AgaData using the EJB variant of the AgaData.initialize() method.

    The arguments are the name of the AgaData and the EJB Context in which the EJB is being run.

  3. Set the data source for the AgaData by calling setDataSource().

  4. Call invokeQuery() to populate the object with data.

  5. Once you have made these calls, you can use the standard AgiRowCursor navigation and manipulation methods.

For example:

  AgaData myAgaData = new AgaData(); 
myAgaData.initialize("MyAgaData", m_context);
myAgaData.setDataSource(DSO_specification);
myAgaData.invokeQuery(DSO_argument);

    For more information on DSOs, Using EJBs with SilverStream Applications and the documentation on AgaData in the SilverStream online API reference.

AgaDatas and their EJB transaction scope

When you use an AgaData in a non-EJB environment, SilverStream uses optimistic concurrency to handle the database updates on calls to updateRows(). When used with EJBs, SilverStream still uses optimistic concurrency; however, the semantics of updateRows() changes slightly, as follows:

Designing EJB applications   Top of page

Designing a good EJB application requires that you follow all of the standard practices when designing any good database application. It also includes the following EJB-specific considerations:






Copyright © 2000, SilverStream Software, Inc. All rights reserved.