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:
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>.java:app/carnot-ejb3/<ServiceImplName>!<LocalEJB3ClassName>.If it can't retrieve a local home object, then it tries to load a remote home object from
ejb/<ServiceName>.java:app/carnot-ejb3/<ServiceImplName>!<RemoteEJB3ClassName>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 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. Please refer to chapter Creating a Runtime Environment with Apache Maven in the Installation Guide section Maven Archetypes of our Stardust Wiki Maven/Basic Setup page for details on how to retrieve a Maven archetype template for Stardust.
EJB2: The carnot.ear archive file contains the JAR
EJB3: The carnot.ear archive file contains the JAR carnot-ejb3.jar with the corresponding deployment descriptors.
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.
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.
These files and libraries have to be available for the application server:
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.
The Stardust EAR contains two application server non-specific descriptors:
application.xml for carnot.ear ejb-jar.xml for carnot-engine.jar (EJB2 only)Note that only EJB2 deployments have the non-specific descriptor ejb-jar.xml.
Whereas EJB3 deployments are completely defined in the vendor-specific deployment descriptor.
For example, for JBoss EAP 6.4:
jboss-ejb3.xml for carnot-ejb3.jar (EJB3 only)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.
The file ,
which is part of the carnot.ear archive,
contains the runtime classes and the deployment descriptors for all EJBs
provided by Stardust, namely:
WorkflowService (Session Bean)AdministrationService (Session Bean)UserService (Session Bean)QueryService (Session Bean)ForkingService (local Session Bean)DocumentManagementService (Session Bean)MessageListener (message-driven bean)DaemonListener (message-driven bean)ResponseHandler (message-driven bean)The general deployment descriptor (as opposed to application
server specific descriptors) for these EJBs in an EJB2 deployment is the .
Note: The Stardust EJBs use container-managed
transaction demarcation. This is already pre-configured in the
and must not be changed.
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>
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 Stardust Portal.
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:
carnot.ear
carnot-engine.jar (EJB2 only)carnot-ejb3.jar (EJB3 only) ipp-portal.war your_custombeans.jar META-INF/application.xmlThe 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.
carnot.ear
carnot-engine.jar
META-INF/MANIFEST.MF Class-Path: your_utils.jaryour_utils.jar META-INF/application.xmlThe 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 ,
contained in the delivered EAR.
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.
It is recommended to use stateless bean deployment for internal authentication as using stateful beans have the following disadvantages:
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:
org.eclipse.stardust.engine.api.ejb2.RemoteServiceFactory with default
(org.eclipse.stardust.engine.api.ejb2.InternallyAuthentifiedSecureSessionFactory)
secure session factoryorg.eclipse.stardust.engine.api.ejb2.EjbEnvServiceFactoryorg.eclipse.stardust.engine.api.web.RemoteWebServiceFactoryThese services are implementations of the interface org.eclipse.stardust.engine.api.runtime.ServiceFactory,
which is an initial entry point to the Stardust Service API.
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.
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.
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
org.eclipse.stardust.engine.api.ejb2.EjbEnvServiceFactoryorg.eclipse.stardust.engine.api.ejb3.EjbEnvServiceFactoryIf 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: 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
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.
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 Stardust'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>
This is an example for using local interface in JBoss. You need to adapt some configuration files, as shown in the following sections.
In the carnot-engine.jar file adapt the following
configuration files:
<session> <ejb-name>WorkflowService</ejb-name> <home>org.eclipse.stardust.engine.api.ejb2.RemoteWorkflowServiceHome</home> <remote>org.eclipse.stardust.engine.api.ejb2.RemoteWorkflowService</remote> <local-home>org.eclipse.stardust.engine.api.ejb2.LocalWorkflowServiceHome</local-home> <local>org.eclipse.stardust.engine.api.ejb2.LocalWorkflowService</local> <ejb-class>org.eclipse.stardust.engine.api.ejb2.beans.RemoteWorkflowServiceImpl</ejb-class>
<session> <ejb-name>WorkflowService</ejb-name> <jndi-name>org.eclipse.stardust.engine.api.runtime.WorkflowService</jndi-name> <local-jndi-name>org.eclipse.stardust.engine.api.runtime.LocalWorkflowService</local-jndi-name>
The following files reside in the JBoss war file of the EAR file:
<ejb-local-ref> to the jboss-web.xml
file:
<ejb-ref> <ejb-ref-name>ejb/WorkflowService</ejb-ref-name> <jndi-name>org.eclipse.stardust.engine.api.runtime.WorkflowService</jndi-name> </ejb-ref> <ejb-local-ref> <ejb-ref-name>ejb/LocalWorkflowService</ejb-ref-name> <local-jndi-name>org.eclipse.stardust.engine.api.runtime.LocalWorkflowService</local-jndi-name> </ejb-local-ref>
<ejb-local-ref> to your web.xml
as shown below:
<ejb-ref> <ejb-ref-name>ejb/WorkflowService</ejb-ref-name> <ejb-ref-type>Session</ejb-ref-type> <home>org.eclipse.stardust.engine.api.ejb2.RemoteWorkflowServiceHome</home> <remote>org.eclipse.stardust.engine.api.ejb2.RemoteWorkflowService</remote> </ejb-ref> <ejb-local-ref> <ejb-ref-name>ejb/LocalWorkflowService</ejb-ref-name> <ejb-ref-type>Session</ejb-ref-type> <local-home>org.eclipse.stardust.engine.api.ejb2.LocalWorkflowServiceHome</local-home> <local>org.eclipse.stardust.engine.api.ejb2.LocalWorkflowService</local> </ejb-local-ref>
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.
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.
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.