Deploying Stardust Components to an EJB Application Server

Deployment to an EJB server is the process of distributing the Stardust J2EE modules and making them available for use by clients. An application server can deploy complete applications (EARs - Enterprise Application Archive) bundling an arbitrary number of library jars.

This chapter covers the following issues:

Deployment Process and Installation

If we summarize the process of deploying an Enterprise Java Bean as installing the EJB JAR or EAR file on an EJB server it includes the following tasks:

We assume that you will install at least two J2EE components:

The service factory EjbEnvServiceFactory first tries to load the local home object from ejb/Local<ServiceName>. If it can't retrieve a local home object, then it tries to load a remote home object from ejb/<ServiceName>. For an example on how to do this using a JBoss server, see Example - Local Interface Usage in JBoss.

The following illustration shows what we want to achieve by following the instruction in the next sections.


Figure: Deployment of the Stardust EJB Component and Model-Specific Components

The Stardust EJB component, which we also refer to as the process engine, is delivered in the archive carnot.ear. The Stardust components provide a pre-packaged carnot.ear file, which you can receive via the archetypes predefined for specific application servers. Refer to the specific application server description in the Application Server Setup part for details on the available archetype.

You can achieve this file by downloading one of the Maven archetype templates from the Stardust artifactory matching your requirements. Refer to chapter Creating a Stardust Runtime Environment with Apache Maven in the Stardust Installation Guide for details.

The carnot.ear archive file contains the JAR carnot-engine.jar with the corresponding deployment descriptors.

 

engine beans
Figure: Beans in the Stardust EJB Component Contained in carnot.ear

Stardust components are delivered with preconfigured deployment descriptors for the common application servers. However, if the user is not satisfied with the default settings, the descriptors can be modified prior to deployment.

Configuring the EJB Server

In general the configuration of your EJB server can be further divided into the following tasks:

For details on your specific application servers, refer to the Application Server Setup documentation.

Application Server Classpath

These files and libraries have to be available for the application server:

Setting Up Transactional Resources

When running in remote mode, the Stardust Engine requires several transactional resources for its operation.

These are:

Having more than one transactional resource requires the use of XA transaction coordination. Refer to the documentation of your application server vendor on how to create the above resources as XA resources.

The required resources are AuditTrail.DataSource for the database communication, CarnotConnectionFactory for the JMS connection factory and a set of JMS queues: CarnotSystemQueue, used internally by the Stardust Engine, CarnotDaemonQueue, used by the daemons, and CarnotApplicationQueue, which is used by the messaging (JMS) applications defined in the models.

Editing Deployment Descriptors

The Stardust EAR contains two application server non-specific descriptors:

Additionally, server vendor-specific deployment descriptors are provided as sample files, named weblogic-ejb-jar.xml (BEA WebLogic) , ejb-borland.xml (Borland Enterprise Server) and jboss.xml (JBoss). If you use an application server with a deployment descriptor editor, you can edit them by using this editor. Otherwise, use a plain text or XML editor to adjust the values.

Deployment Descriptors for carnot-engine.jar

The file carnot-engine.jar, which is part of the carnot.ear archive, contains the runtime classes and the deployment descriptors for all EJBs provided by Stardust, namely:

The general deployment descriptor (as opposed to application server specific descriptors) for these EJBs is the ejb-jar.xml file.

Note: The Stardust EJBs use container-managed transaction demarcation. This is already pre-configured in the ejb-jar.xml and must not be changed.

Application Archive Deployment Descriptors

Stardust application deployment descriptors are in the file application.xml and contain the following entries.

<?xml version="1.0"  encoding="UTF-8"?>
<!DOCTYPE application PUBLIC "-//Sun Microsystems, Inc.//DTD J2EE Application 1.3//EN" "http://java.sun.com/dtd/application_1_3.dtd">
<application>
<display-name>CARNOT</display-name>
<module>
<ejb>carnot-engine.jar</ejb>
</module>
<module>
<web><web-uri>ipp-portal.war</web-uri><context-root>carnot/ipp-portal</context-root></web>
</module>
</application>

Since the file only describe which modules are included in the application, you need to change this file only if you bundle your module with carnot.ear in a separate jar module. In this case we find two application modules, the process engine and the Stardust Portal.

Bundling your model-specific JARs within the EAR File

The Enterprise Java Beans TM you have integrated in your model also need to be deployed to the same application server. They must be collected in one or more additional JARs if your custom classes will fall into the following categories:

The first two categories will always be bundled within the carnot.ear.

If your custom JARs contain Enterprise Beans, the structure of the EAR will be as follows:

The JAR your_custombeans.jar must contain the corresponding deployment descriptors and must be added as a module to the application.xml.

If your custom classes are only utility classes which are referenced directly by the Stardust Engine, you have to use the Class-Path mechanism which allows a J2EE .jar file to reference utility classes, other shared classes or resources packaged in a separate .jar file that is included in the same J2EE application package. A Class-Path header has to be added in the referencing .jar file's Manifest file.

The same mechanism can be used if you have more than one JAR with Enterprise Beans which share the same utility classes.

In those application servers which allow you to choose between class loader policies, you may package your beans separately and set the class loader policy to container. In these application servers, for better performance, the deployer can also directly deploy the JAR file carnot-engine.jar, contained in the delivered EAR.

Deploying an EAR file to an EJB Container

The installation of an EAR in an EJB container generally consists of the following steps:

For many application servers that support hot deployment, the deployment of Stardust will just require copying the EAR to a specific location. The JNDI names for the Stardust EJBs ( WorkflowService, AdministrationService, UserService, QueryService, MessageListener, DaemonListener and ResponseHandler) are usually specified in the application server specific deployment descriptors. Refer to the documentation of the application server you use in section Application Server Setup and the application server vendor user guide for more details on that. By default, the predefined JNDI names are in the form org.eclipse.stardust.engine.api.runtime.<ejb_name>.

To perform the deployment steps, we recommend using the application server's administrative tools. For detailed information on performing these steps, consult user guides provided with the corresponding application servers.

Stateless Bean Deployment for Internal Authentication

It is recommended to use stateless bean deployment for internal authentication as using stateful beans have the following disadvantages:

  1. they are removed on any non-application exception and
  2. they are having timeouts.

Use stateful only for specific cases, e.g. if working without ServiceFactory and accessing the bean directly.

If the stateless mode is not enabled by default, adjust the server side EJB deployment descriptor to use the tunneling variant of the service interfaces and beans. You can use the following file ejb-jar-tunneling-example.xml to replace your deployment descriptor ejb-jar.xml or manually adjust it. For example for the WorkflowService adjust the following entries:

<ejb-name>WorkflowService</ejb-name>
<home>org.eclipse.stardust.engine.api.ejb2.tunneling.TunnelingRemoteWorkflowServiceHome</home>
<remote>org.eclipse.stardust.engine.api.ejb2.tunneling.TunnelingRemoteWorkflowService</remote>
<local-home>org.eclipse.stardust.engine.api.ejb2.tunneling.TunnelingLocalWorkflowServiceHome</local-home>
<local>org.eclipse.stardust.engine.api.ejb2.tunneling.TunnelingLocalWorkflowService</local>
<ejb-class>org.eclipse.stardust.engine.api.ejb2.tunneling.beans.TunnelingWorkflowServiceImpl</ejb-class>
<session-type>Stateless</session-type>

Now the client side automatically detects if the tunneling interfaces are being used and adjust if needed. This is implemented for the following services:

These services are implementations of the interface org.eclipse.stardust.engine.api.runtime.ServiceFactory, which is an initial entry point to the Stardust Service API.

Usage of Local Interfaces

If client code (portals, servlets, custom session code, etc. ) and server (engine, services beans) are running in the same JVM (application server instance), then the performance can be improved by configuring the usage of the local service interfaces.

Server-side

As described in the above sections, to make local lookups possible, the engine's deployment descriptor has to contain the local and local-home interfaces for all services.

In a stateful deployment or if principal-based security is enabled, the interfaces org.eclipse.stardust.engine.api.ejb2.Local*ServiceHome and org.eclipse.stardust.engine.api.ejb2.Local*Service should be configured.

In a stateless deployment that uses internal security, the tunneling local and local-home interfaces org.eclipse.stardust.engine.api.ejb2.tunneling.TunnelingLocal*ServiceHome and org.eclipse.stardust.engine.api.ejb2.tunneling.TunnelingLocal*Service have to be used. Hence the example shown above would be extended to:

<ejb-name>WorkflowService</ejb-name>
<home>org.eclipse.stardust.engine.api.ejb2.tunneling.TunnelingRemoteWorkflowServiceHome</home>
<remote>org.eclipse.stardust.engine.api.ejb2.tunneling.TunnelingRemoteWorkflowService</remote>
<local-home>org.eclipse.stardust.engine.api.ejb2.tunneling.TunnelingLocalWorkflowServiceHome</local-home>
<local>org.eclipse.stardust.engine.api.ejb2.tunneling.TunnelingLocalWorkflowService</local>
<ejb-class>org.eclipse.stardust.engine.api.ejb2.tunneling.beans.TunnelingWorkflowServiceImpl</ejb-class>
<session-type>Stateless</session-type>

Depending on the application server you use, you may also have to provide similar information in the application server specific deployment descriptor or when deploying the EAR file.

Client-side

The server-side configuration only enables the usage of the local interfaces on the server-side. To make the client actually use the local interfaces, the client configuration has to be modified as well.

No changes to the client code are required. If your client code uses the org.eclipse.stardust.engine.api.runtime.ServiceFactoryLocator, then the ServiceFactory that is encapsulating the actual service lookup is configured via the property Client.ServiceFactory. Thus, to enable the local interface usage on client side, set the property to the class org.eclipse.stardust.engine.api.ejb2.EjbEnvServiceFactory.

If you also want to enable local interface usage for Web clients, which are deployed inside the same EAR file, e.g. for the Stardust portals, you should use the same service factory for the property Web.ServiceFactory:

Client.ServiceFactory = org.eclipse.stardust.engine.api.ejb2.EjbEnvServiceFactory

Web.ServiceFactory = org.eclipse.stardust.engine.api.ejb2.EjbEnvServiceFactory

! Tip: Depending on your packaging and class loading strategy the client code could be using its own client-side carnot.properties file (e.g. in a WAR file) or share the properties file with the server-side (carnot-engine.jar). In most cases it is the most convenient approach to have just one merged client- and server-side carnot.properties file that resides outside the ear file in the server classpath and no carnot.properties files in the individual application archives (WARs, EJB jars).

The deployment descriptor of the client (WAR or EJB jar) has to declare a local reference to the local service that will be looked up.

The EJBEnvServiceFactory performs the local service lookup using

paramContext.lookup("ejb/Local" + serviceName);

Therefore the deployment descriptor has to contain local EJB references for the service names ejb/Local*Service. Otherwise the lookup fails and the EJBEnvServiceFactory will try a fallback to the remote interface.

The local and local-home interfaces specified in this reference should match the interfaces declared on the server side. If a stateless deployment with internal security is configured for the services, then the client should also declare the tunneling interfaces in its deployment descriptor. Otherwise the client can also declare the interfaces org.eclipse.stardust.engine.api.ejb2.Local*ServiceHome and org.eclipse.stardust.engine.api.ejb2.Local*Service.

For instance the deployment descriptor of a session bean using the Stardust API and the EJBEnvServiceFactory should contain the following ejb-local-ref entries, if the services are deployed stateless and uses internal security:

<enterprise-beans>
    <session id="Session_1">
        <ejb-name>your.Service</ejb-name>
        <home>your.ServiceHome</home>
        <remote>your.Service</remote>
        <local-home>your.ServiceLocalHome</local-home>
        <local>your.ServiceLocal</local>
        <ejb-class>your.Class</ejb-class>
        <session-type>Stateless</session-type>
        <transaction-type>Container</transaction-type>
        <ejb-local-ref id="EJBLocalRef_1264579477348">
            <ejb-ref-name>ejb/UserService</ejb-ref-name>
            <ejb-ref-type>Session</ejb-ref-type>
            <local-home>org.eclipse.stardust.engine.api.ejb2.tunneling.TunnelingLocalUserServiceHome</local-home>
            <local>org.eclipse.stardust.engine.api.ejb2.tunneling.TunnelingLocalUserService</local>
            <ejb-link>UserService</ejb-link>
        </ejb-local-ref>
        <ejb-local-ref id="EJBLocalRef_1264579477349">
            <ejb-ref-name>ejb/QueryService</ejb-ref-name>
            <ejb-ref-type>Session</ejb-ref-type>
            <local-home>org.eclipse.stardust.engine.api.ejb2.tunneling.TunnelingLocalQueryServiceHome</local-home>
            <local>org.eclipse.stardust.engine.api.ejb2.tunneling.TunnelingLocalQueryService</local>
            <ejb-link>QueryService</ejb-link>
        </ejb-local-ref>
        <ejb-local-ref id="EJBLocalRef_1264579477350">
            <ejb-ref-name>ejb/WorkflowService</ejb-ref-name>
            <ejb-ref-type>Session</ejb-ref-type>
            <local-home>org.eclipse.stardust.engine.api.ejb2.tunneling.TunnelingLocalWorkflowServiceHome</local-home>
            <local>org.eclipse.stardust.engine.api.ejb2.tunneling.TunnelingLocalWorkflowService</local>
            <ejb-link>WorkflowService</ejb-link>
        </ejb-local-ref>
        <ejb-local-ref id="EJBLocalRef_1264579477351">
            <ejb-ref-name>ejb/AdministrationService</ejb-ref-name>
            <ejb-ref-type>Session</ejb-ref-type>
            <local-home>org.eclipse.stardust.engine.api.ejb2.tunneling.TunnelingLocalAdministrationServiceHome</local-home>
            <local>org.eclipse.stardust.engine.api.ejb2.tunneling.TunnelingLocalAdministrationService</local>
            <ejb-link>AdministrationService</ejb-link>
        </ejb-local-ref>     
    </session>

Depending on the application server that you use, you may also have to provide similar information in the application server specific deployment descriptor for your client code or when deploying the EAR file.

API Usage from inside a Process Instance

If you are using the API from inside code that is executed as part of a process instance, then this code also has to be considered as a client. The code will be executed inside a thread that is triggered by the WorkflowService, the AdministrationService or be the ForkingService. It will run in the EJB context of one of those services and also use the ServiceFactory that is configured as Client.ServiceFactory. As usual, the EJBEnvServiceFactory will look up the service interface via ejb/Local*Service in the context of the Stardust's session beans. Hence, in this scenario you will have to add ejb-local-ref entries to the deployment descriptor of the engine's session beans.

The only special thing about this case is that the engine acts as service consumer / client and as service provider / server. For instance, the WorkflowService could be used from a Web portal to trigger a process instance. Thus, the thread/process instance could be running in the EJB context of the workflow service. Then, as part of the running process instance, code using the engine WorkflowService API and the EJBEnvServiceFactory, could be invoked. As a result, the EJBEnvServiceFactory would look up the local interface via ejb/LocalWorkflowService in the context of the WorkflowService. The required part in the carnot-engine.jar deployment descriptor could look like the following:

<session id="Session_WorkflowService">
    <ejb-name>WorkflowService</ejb-name>
    <home>org.eclipse.stardust.engine.api.ejb2.tunneling.TunnelingRemoteWorkflowServiceHome</home>
    <remote>org.eclipse.stardust.engine.api.ejb2.tunneling.TunnelingRemoteWorkflowService</remote>
    <local-home>org.eclipse.stardust.engine.api.ejb2.tunneling.TunnelingLocalWorkflowServiceHome</local-home>
    <local>org.eclipse.stardust.engine.api.ejb2.tunneling.TunnelingLocalWorkflowService</local>
    <ejb-class>org.eclipse.stardust.engine.api.ejb2.tunneling.beans.TunnelingWorkflowServiceImpl</ejb-class>
    <session-type>Stateless</session-type>
    <transaction-type>Container</transaction-type>
    <ejb-local-ref id="EJBLocalRef_WorkflowService_ForkingService">
        <ejb-ref-name>ejb/ForkingService</ejb-ref-name>
        <ejb-ref-type>Session</ejb-ref-type>
        <local-home>org.eclipse.stardust.engine.api.ejb2.beans.LocalForkingServiceHome</local-home>
        <local>org.eclipse.stardust.engine.api.ejb2.beans.LocalForkingService</local>
        <ejb-link>ForkingService</ejb-link>
    </ejb-local-ref>
    <ejb-local-ref id="EJBLocalRef_WorkflowService_LocalWorkflowService">
        <ejb-ref-name>ejb/LocalWorkflowService</ejb-ref-name>
        <ejb-ref-type>Session</ejb-ref-type>
        <local-home> org.eclipse.stardust.engine.api.ejb2.tunneling.TunnelingLocalWorkflowServiceHome </local-home>
        <local>ag org.eclipse.stardust.engine.api.ejb2.tunneling.TunnelingLocalWorkflowService </local>
        <ejb-link>WorkflowService</ejb-link>
    </ejb-local-ref>

Example - Local Interface Usage in JBoss

This is an example for using local interface in JBoss. You need to adapt some configuration files, as shown in the following sections.

Example Configuration in EJB-Jar-File for JBoss

In the carnot-engine.jar file adapt the following configuration files:

WAR in JBoss

The following files reside in the JBoss war file of the EAR file:

To summarize, if you have set the <ejb-local-ref> entry properly in the data type definitions and the following property in your carnot.properties file:

Web.ServiceFactory = org.eclipse.stardust.engine.api.ejb2.EjbEnvServiceFactory

the portal WARs can use local interfaces as well.

Deploying Spring Bean Applications

To execute Spring applications in an EJB environment, you have to prepare the deployment. For details on the necessary configuration refer to section Configuring the Stardust Deployment of chapter Runtime Setup of the Spring Integration Guide.

Known Issues

Deployment Warnings for Missing Validation Classes

During an EJB deployment, the engine searches for validation classes. If they are be detected, they will be used, otherwise a deployment warning is generated, which can be ignored. This is different for interactive applications. No warning is generated for them as it is assumed that they are unknown to the engine in any case. However a ClassNotFoundException is logged, but these exceptions will not interrupt the deployment.

Linkage Error occurs in some environments in case activities use Structured Data

In case you start your server with JDK 1.6 and a patchlevel less than 20, a LinkageError error might occur during the deployment as this JDK version contains an earlier version of the jaxb-api.jar. To avoid this problem, use a JDK version 1.5 or use JDK version 1.6 with a patchlevel value greater or equal 20. In case switching to another JDK version is not possible, you can also provide a newer version of an endorsed standard than those included in the Java platform by copying an updated jaxb-api.jar file to your <java-home>/lib/endorsed folder.