Deploying Infinity Process Platform Components to an EJB Application Server

Deployment to an EJB server is the process of distributing the Infinity Process Platform 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

or

If it can't retrieve a local home object, then it tries to load a remote home object from

or

For example, 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 Infinity Process Platform EJB Component and Model-Specific Components

The Infinity Process Platform EJB component, which we also refer to as the process engine, is delivered in the archive carnot.ear. The Infinity Process Platform 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 Infinity Process Platform artifactory matching your requirements. Please refer to chapter Creating a Runtime Environment with Apache Maven in the Installation Guide section Maven Archetypes of our Infinity Process Platform Wiki Maven/Basic Setup page for details on how to retrieve a Maven archetype template for IPP.

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

EJB3: The carnot.ear archive file contains the JAR carnot-ejb3.jar with the corresponding deployment descriptors.

engine beans
Figure: Beans in the Infinity Process Platform EJB Component Contained in carnot.ear

Infinity Process Platform 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 Infinity Process Platform 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 Infinity Process Platform Engine, CarnotDaemonQueue, used by the daemons, and CarnotApplicationQueue, which is used by the messaging (JMS) applications defined in the models.

Editing Deployment Descriptors

The Infinity Process Platform EAR contains two application server non-specific descriptors:

Additionally, for EJB2 deployments 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.

Provided EJB3 vendor specific deployment descriptors are contained in the carnot-ejb3.jar.

Deployment Descriptors for carnot-engine.jar (EJB2) or carnot-ejb3.jar (EJB3)

The file carnot-engine.jar (EJB2) or carnot-ejb3.jar (EJB3), which is part of the carnot.ear archive, contains the runtime classes and the deployment descriptors for all EJBs provided by Infinity Process Platform, namely:

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

Note: The Infinity Process Platform 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

Infinity Process Platform application deployment descriptors are in the file application.xml and contain the following entries.

EJB2 application.xml
<?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>
EJB3 application.xml

Note: EJB3 deployments also require to specify the <application-name>carnot</application-name>.

<?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-ejb3.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 Infinity Process Platform 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 Infinity Process Platform 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 Infinity Process Platform will just require copying the EAR to a specific location. The JNDI names for the Infinity Process Platform 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.

EJB3 deployments are in stateless mode, by default and need not to be changed. The org.eclipse.stardust.engine.api.ejb2.RemoteServiceFactory looks up the EJB3 beans using following JNDI name:

ejb:carnot/" + provider.getEJB3ModuleName() + "/" + provider.getName() + "Impl!" + remoteEJB3ClassName

Example:

ejb:carnot/carnot-ejb3/WorkflowServiceImpl! org.eclipse.stardust.engine.api.ejb3.beans.RemoteWorkflowService

For EJB2 deployments, 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 Infinity Process Platform 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

For EJB3 no changes are required.

For EJB2 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

For EJB2 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 for

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

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

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

and for EJB3:

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

Web.ServiceFactory = org.eclipse.stardust.engine.api.ejb3.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.

In EJB3 deployments, the EJBEnvServiceFactory performs the local service lookup using:

paramContext.lookup("java:app/" + provider.getEJB3ModuleName() + "/" + provider.getName() + "Impl!" + localEJB3ClassName);

Example

java:app/carnot-ejb3/WorkflowServiceImpl!
org.eclipse.stardust.engine.api.ejb3.beans.WorkflowService

No other configuration is required.

For EJB2, 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 Infinity Process Platform 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

In EJB3 deployments, it is sufficient to configure the org.eclipse.stardust.engine.api.ejb3.EjbEnvServiceFactory as Client.ServiceFactory to enable local service lookups. EJB2 deployments need following configuration.

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 (for EJB2) in the context of the Infinity Process Platform's session beans. Hence, in this scenario in an EJB2 deployment 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 EJB2 Deployment

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

Example - EJB2 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 Infinity Process Platform 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.