2. Concurrency and thread safety: The container
employs concurrency or thread safety.
Remoting and web services: RMI and SOAP
Webservices.
Transaction and security management: Session
beans use pure configuration-based
transactions, authorization, and authentication.
Timer services and interceptors: Interceptors are
EJB’s version of AOP, Timer services is nothing
but schedulers.
3. EJB3:
Provides robust support for accessing remote components or the
ability to seamlessly expose your business logic as web services.
Provides instance pooling, automated session state maintenance,
and passivation/activation.
It is an integral part of the Java EE standard.
It provides portability, standardization, and vendor support.
Spring:
Provides elegant utilities such as JdbcTemplate and JmsTemplate.
It has has great DI which only works for container components in
EJB 3
Spring AOP or AspectJ is a much more feature-rich choice than EJB
3 interceptors.
4. Each session bean implementation has two distinct
parts—one or more bean interfaces and a bean
implementation class.
Interface-based programming is the practice of not
using implementation classes directly whenever
possible promoting loose coupling.
An interface through which a client invokes the bean is
called a business interface.
A business interface can be remote or even web
service-accessible.
A single EJB can have multiple interfaces i.e. EJB
implementation classes can be polymorphic, meaning
that different clients using different interfaces could
use them in completely different ways.
5. Each interface that the bean intends to support must
be explicitly included in the bean implementation
class.
Session bean implementation classes can never be
abstract, which means that all methods mandated by
declared business interfaces must be implemented in
the class.
The EJB implementation classes can have nonprivate
methods that are not accessible through any interface
useful for creating clever unit-testing frameworks.
An EJB bean class can make use of OO inheritance
putting commonly used logic in a parent POJO class.
6. A session bean must have at least one business interface.
The session bean class must be concrete and cannot be defined as
either final or abstract since the container needs to manipulate it.
There must be a no-argument constructor in the bean class as it is
invoked by the container to instantiate the bean.
A session bean class can subclass another session bean or any other
POJO.
The business methods and lifecycle callback methods may be defined
either in the bean class or in a superclass.
Annotation inheritance is supported with several limitations with EJB 3
session beans. (e.g. @Stateless or @Stateful defined in parent class is
ignored in child class but not for resource injection annotations.)
Business method names must not start with “ejb.” because it may
interfere with EJB infrastructure processing.
Define all business methods as public, but not final or static.
The arguments and the return type of the method implement the
java.io.Serializable interface when method is exposed in remote
business interface.
7. A particular business process may involve more
than one session bean method call during which
it can maintain a conversational state.
A bean that maintains conversational state
“remembers” the results of previous exchanges,
and is a stateful session bean.
Stateful session beans tend to model multistep
workflows, while stateless session beans tend to
model generalpurpose, utility services used by
the client.
8. The container manages almost every aspect of
session beans which enables it to provide
abstractions including DI, automated
transaction management, AOP, transparent
security management.
9. The lifecycle for a session bean starts when a bean instance is
created.
The creation happens when a client receives a reference to the
bean either by doing a JNDI lookup or by using dependency
injection.
Steps involved in initializing a Bean:
The container invokes the newInstance method on the bean
object, which essentially translates to a constructor invocation
on the bean implementation class.
If the bean uses DI, all dependencies on resources, other
beans, and environment components are injected into the
newly created bean instance.
After the container determines that an instance is no longer
needed, the instance is destroyed.
The callbacks allow the bean to be notified when some of its
lifecycle transitions happen.
10.
11. Lifecycle callbacks are bean methods (not exposed by a business
interface) that the container calls to notify the bean about a
lifecycle transition, or event.
When the event occurs, the container invokes the corresponding
callback method, and which can be used to perform business logic
or operations such as initialization and cleanup of resources.
A PostConstruct callback is invoked just after a bean instance is
created and dependencies are injected.
A PreDestroy callback is invoked just before the bean is destroyed
and is helpful for cleaning up resources used by the bean.
The process in which the container decides to deactivate a stateful
bean instance temporarily when not in use is called passivation.
The process in which the container activates the bean instance
again when the client needs it called activation.
The @PrePassivate and @PostActivate annotations apply to the
passivation and activation lifecycle events.
A lifecycle callback method either in the bean class or in a separate
interceptor class.
12. Callback Annotation Type of EJB Typically Used For...
javax.annotation.
PostConstruct
Stateless, stateful,
MDB
Invoked after a bean
instance is created and
dependency
injection is complete.
javax.annotation.
PreDestroy
Stateless, stateful,
MDB
invoked prior
to a bean instance being
destroyed.
javax.ejb.
PrePassivate
Stateful invoked prior
to a bean instance being
passivated.
javax.ejb.
PostActivate
Stateful invoked after
a bean instance is
activated
13. Stateless session beans don’t maintain
conversational state and are the most
performance efficient.
The stateless beans are pooled i.e. for each
managed bean, the container keeps a certain
number of instances handy in a pool.
For each client request, an instance from the
pool is quickly assigned to the client.
When the client request finishes, the instance is
returned to the pool for reuse.
14. @Target(TYPE) @Retention(RUNTIME)
public @interface Stateless {
String name() default "";
String mappedName() default "";
String description() default "";
}
Name specifies the name of the bean and is also used to bind
the EJB to the global JNDI tree (server’s managed resource
registry).
If the name parameter is omitted, the container assigns the
name of the class to the bean.
MappedName is a vendor-specific name that can be assigned
to the EJB.
15. Local interface: It is designed for clients with the beans
collocated in the same container (JVM) instance.
An interface can be designated as a local business interface by
using the @Local annotation.
Remote interface: It is designed for clients with beans residing
outside the EJB container’s JVM instance.
EJB 3 enables a stateless bean to be made accessible via RMI
through the @Remote annotation.
A remote business interface may extend java.rmi.Remote.
All parameters and return types of remote business interface
methods must be Serializable.
Web service endpoint interface: It is the ability to expose a
stateless session bean as a SOAP-based web service.
The @WebService annotation doesn’t place any special
restrictions on either the interface or the implementing bean.
16. We cannot mark the same interface with more than
one access type annotation.
A business interface can extend another interface, and
can remove code duplication by creating a business
interface that has common methods and business
interfaces that extend the common “parent” interface.
To apply the @Local, @Remote, or @WebService
annotation in the bean class without having to
implement the business interface as follows:
@Remote(BidManager.class)
@Stateless
public class BidManagerBean { ... }
17. Creates bean instances using the default constructor as
needed.
Injects resources such as database connections.
Puts instances in a managed pool.
Pulls an idle bean out of the pool when an invocation
request is received from the client (the container may
have to increase the pool size at this point).
Executes the requested business method invoked
through the business interface by the client.
When the business method finishes executing, pushes
the bean back into the “method-ready” pool.
As needed, retires (a.k.a. destroys) beans from the
pool.
18. There are two types of stateless session bean lifecycle
callback methods:
Callbacks that are invoked when the PostConstruct
event occurs immediately after a bean instance is
created and set up, and all the resources are injected.
Callbacks that are invoked when the PreDestroy event
occurs, right before the bean instance is retired and
removed from the pool.
There can be multiple PostConstruct and PreDestroy
callbacks for a given bean in a class or in a separate
interceptor class.
The lifecycle callback methods embedded in the bean
i.e. initialize and cleanup methods cannot throw
checked exceptions.
19. Unlike with stateless beans, the container makes sure
that subsequent method invocations by the same
client are handled by the same stateful bean instance.
The one-to-one mapping between a client and a bean
instance makes saving bean conversational state.
Bean instances cannot be readily returned to the pool
and reused while a client session is still active.
The Bean instance waits for the next request from the
client owning the session.
The stateful session bean instances held by a large
number of concurrent clients can have a significant
memory footprint.
20. Stateful bean instance variables used to store
conversational state must be Java primitives or
Serializable objects.
Since stateful session beans cannot be pooled and
reused, they should be a way to destroy when too
many of them are accumulated.
Business method must be defined for removing the
bean instance by the client using the @Remove
annotation.
Stateful session beans have the PrePassivate (before
passivation of bean instance) and PostActivate (after a
bean instance is bought back to memory) lifecycle
callback methods.
21. Stateful session beans support local and
remote invocation through the @Local and
@Remote annotations.
A stateful session bean cannot have a web
service endpoint interface because SOAP-
based web services are inherently stateless
in nature.
There should be at least one @Remove
annotated method in your stateful bean’s
business interface.
22. Always creates new bean instances using the default constructor
whenever a new client session is started.
Injects resources.
Stores the instance in memory.
Executes the requested business method invoked through the
business interface by the client.
Waits for and executes subsequent client requests.
If the client remains idle for a period of time, the container
passivates the bean instance. Essentially, passivation means that the
bean is moved out of active memory, serialized, and stored in
temporary storage.
If the client invokes a passivated bean, it is activated (brought back
into memory from temporary storage).
If the client does not invoke a passivated bean instance for a period
of time, it is destroyed.
If the client requests the removal of a bean instance, it is first
activated if necessary and then destroyed.
23.
24. If clients don’t invoke a bean for a long enough time,
the bean is not kept in memory to avoid out of
memory issues. Such technique is called passivation.
Passivation means saving a bean instance into disk
instead of holding it in memory by serializing the entire
bean instance and moving it into permanent storage.
Activation is the opposite of passivation and is done by
retrieving the bean instance from permanent storage,
deserializing it, and moving it back into memory.
The point of the PrePassivate callback is to give the
bean a chance to prepare for serialization.
The point of the PostActivate callback is getting hold of
resources that either are not instantiated or were lost
during the serialization/deserialization process.
25. Calling business methods marked with the
@Remove annotation signifies a desire by the
client to end the session by immediate bean
destruction.
It is critical to remove the stateful bean
instances when the client is finished with its
work instead of relying on the container to
destroy them when they time out.
26. Features Stateless Stateful
Conversational state No Yes
Pooling Yes No
Performance problems Unlikely Possible
Lifecycle events PostConstruct,
PreDestroy
PostConstruct, PreDestroy,
PrePassivate, PostActivate
Timer Yes No
SessionSynchronization
for transactions
No Yes
Web services Yes No
Extended
PersistenceContext
No Yes
27. The client obtains a reference to the session
beans directly or indirectly from JNDI.
All session bean invocations are made through
an interface appropriate for the access type.
The client makes as many method calls as are
necessary to complete the business task at
hand.
In case of a stateful session bean, the last client
invocation should be a remove method.
28. The @EJB annotation is specifically intended for injecting session
beans into client code
The injection is only possible within managed environments in code
running inside an application-client container or in components
registered with the web container.
@Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME)
public @interface EJB {
String name() default "";
Class beanInterface() default Object.class;
String beanName() default "";
}
The name element suggests the JNDI name that is used to bind the
injected EJB in the environment-naming context. It is derived from
the interface name if the JNDI name is absent.
The beanInterface specifies the business interface to be used to
access the EJB.
The beanName element allows us to distinguish among EJBs if
multiple EJBs implement the same business interface.
29. A stateful session can be injected into
another stateful session bean instance.
A stateful session bean should not be
injected into a stateless object, such that a
stateless session bean or servlet may be
shared by multiple concurrent clients.
Injecting an instance of a stateless session
bean into a stateful session bean is
perfectly legal.
30. EJB 3 adds extended persistence contexts
specifically geared toward stateful session
beans.
Application servers provide high availability by
clustering EJB containers running the same
stateful bean.
A clustered EJB container replicates session
state across container instances.
It is routed to another container instance
seamlessly on crash of clustered container
instance without losing state.
31. The data stored in the conversation state should be
examined to have a minimal total memory footprint
for the stateful bean.
The conversational state is replicated between
different instances of the EJB container.
Improper use of passivation policies causes
performance problems.
Explicitly removing the outdated bean instances
rather than depending on the container to time them
out solving the potential memory problems.
Annotating a method using @Remove annotation
signals the container to remove the bean instance.
32. Replacing stateful beans with a combination of
persistence and stateless processing, by moving state
information from memory to the database on every
request.
Building a mechanism at the client side to maintain state,
such as storing the state as an object in client memory or
in a file.
Both approaches don’t guarantee high availability of the
application, automated passivation and robust,
transparent state maintenance.
Session state can be maintained in the web container
using HttpSession object of Servlet API, but too much data
in HttpSession could decrease performance of the servlet
container and is not applicable for thick or Java SE clients.
33. Choose bean type carefully: Examine if application needs stateful
session beans.
Examine interface types for session beans: Remote interfaces
involve network access slowing down the application and must be
avoided for local interface for client using same JVM.
In DI, a stateful session bean should not be injected into a
stateless session bean or servlet.
Separate crosscutting concerns such as logging and auditing using
business interceptors.
Closely examine the kind of data being stored in the conversation
state: Use small, primitive instance variables in a stateful bean
whenever possible as opposed to large nested composite objects.
Don’t forget to define remove methods in a stateful session bean.
Tune passivation and timeout configurations to find the optimal
values for your application.
34. Point to Point Messaging: A single message travels from a
single producer (point A) to a single consumer (point B).
PTP message destinations are called queues.
PTP doesn’t guarantee that messages are delivered in any
particular order.
If more than one potential receiver exists for a message, a
random receiver is chosen.
A single producer produces a message that is received by any
number of consumers who happen to be connected to the
destination at the time.
The message destination in this model is called a topic and a
consumer is called a subscriber.
Pub-sub messaging works particularly well in broadcasting
information across systems
35. A third kind of model called request-reply gives
the message receiver enough information so
that they might “call us back.” typically
implemented on top of either the PTP or pub-
sub models.
37. Administrative Objects are resources that are created and
configured outside the code and stored in JNDI.
JMS has two administrative objects:
javax.jms.ConnectionFactory and javax.jms.Destination.
Connection factory retrieved using dependency injection with
the @Resource annotation which contains all the configuration
information needed to connect to MOM.
createConnection method creates a live MOM connection
which is thread-safe and designed to be sharable.
JMS session provides a single-threaded, task-oriented context
for sending and receiving messages.
The first parameter of the createSession method specifies
whether the session is transactional, i.e. messages won’t be
realized until either the session is closed or commited.
MessageProducer is used to send messages using the send
method to the shipping request queue.
38. The Message interface standardizes what is exchanged
across JMS and is an extremely robust data encapsulation
mechanism.
JMS message has the following parts: the message header,
message properties, and the message body.
Headers are name-value pairs common to all messages.
Message properties are similar to headers, but are
explicitly created by the application instead of being
standard across messages.
A property can be a boolean, byte, double, float, int, long,
short, String, or Object.
The message body contains the contents of the envelope; it
is the payload of the message.
40. MDBs can receive messages from any enterprise information
system (EIS) using the Java EE Connector Architecture (JCA).
Messages can be sent to an MDB by implementing a JCA-
compliant adapter/connector that includes support for message
inflow contract.
Once JCA resource adapter or connector is deployed to a Java EE
container, the message inflow contract can be used to have an
asynchronous message delivered to an endpoint inside the
container.
A JCA endpoint is essentially the same as a JMS destination—it
acts as a server proxy to an MDB (a message consumer/listener in
JMS terms).
As soon as a message arrives at the endpoint, the container
triggers any registered MDBs listening to the endpoint and
delivers the message to it.
The MDB implements a listener interface that is appropriate to
the JCA connector/message type and passes activation
configuration parameters to the JCA connector and registers as a
listener to the JCA connector.
41. Multithreading: Provides multithreaded
message consumers that can process messages
concurrently by managing incoming messages
among multiple instances of beans.
As soon as a new message reaches the
destination, an MDB instance is retrieved from
the pool to handle the message.
42. Simplified messaging code: MDBs relieves
from coding the mechanical aspects of
processing messages by using sensible defaults
for common circumstances or, by using simple
annotations or deployment descriptor for
custom configuration.
Starting message consumption: Invocation of
the appropriate method to start picking up
messages from the shipping request queue.
43. The MDB class must directly (using the implements keyword in
class declaration) or indirectly (through annotations or
descriptors) implement a message listener interface.
The MDB class must be concrete and cannot be either a final or
an abstract class.
The MDB must be a POJO class and not a subclass of another
MDB.
The MDB class must be declared public.
The bean class must have a no-argument constructor (default
constructor).
A finalize method cannot be defined in the bean class. The
PreDestroy method should be defined for any cleanup code if
necessary.
The methods defined in the message listener interface must be
impemented and should be public and cannot be static or final.
The javax.rmi.RemoteException or any runtime exceptions
should not be thrown for any method. If a RuntimeException is
thrown, the MDB instance is terminated.
46. @Target(TYPE)
@Retention(RUNTIME)
public @interface MessageDriven {
String name() default "";
Class messageListenerInterface default Object.class;
ActivationConfigProperty[] activationConfig() default {};
String mappedName();
String description();
}
The name parameter specifies the name of the MDB.
If the name element is omitted, the code uses the name of the class.
The messageListenerInterface specifies which message listener the MDB
implements.
The last parameter, activationConfig, is used to specify listener-specific
configuration properties.
47. The container uses the MessageListener interface to
register the MDB with the message provider and to
pass incoming messages by invoking implemented
message listener methods.
@MessageDriven(
name="ShippingRequestJMSProcessor",
messageListenerInterface="javax.jms.MessageListen
er")
public class ShippingRequestProcessorMDB { .. }
public class ShippingRequestProcessorMDB
implements MessageListener { .. }
48. The activationConfig property of the @MessageDriven annotation
allows to provide messaging system–specific configuration information
through an array of ActivationConfigProperty instances.
public @interface ActivationConfigProperty {
String propertyName();
String propertyValue();
}
Each activation property is essentially a name-value pair that the
underlying messaging provider understands and uses to set up the
MDB.
Most common JMS activation configuration properties: destinationType,
connectionFactoryJndiName, and destinationName.
The destinationType property tells the container this JMS MDB is
listening to a javax.jms.Queue or javax.jms.Topic.
The connectionFactoryJndiName specifies the JNDI name of the
connection factory that should be used to create JMS connections for
the MDB.
The destinationName parameter specifies that we are listening for
messages arriving at a destination with the JNDI name of
jms/ShippingRequestQueue.
49. Messages are not actually removed from the
queue until the consumer acknowledges them.
(default is AUTO_ACKNOWLEDGE).
We could change the acknowledge mode to
DUPS_OK_ACKNOWLEDGE as follows:
@ActivationConfigProperty(
propertyName="acknowledgeMode",
propertyValue="DUPS_OK_ACKNOWLEDGE")
50. Acknowledgment Mode Description Supported with
MDB
AUTO_ACKNOWLEDGE The session automatically acknowledges
receipt after a message has been received
or is successfully processed.
YES
CLIENT_ACKNOWLEDGE Have to manually acknowledge the
receipt of the message by calling the
acknowledge method on the message.
NO
DUPS_OK_
ACKNOWLEDGE
The session can lazily acknowledge
receipt of the message. This is similar to
AUTO_ACKNOWLEDGE but useful
when the application can handle delivery
of duplicate messages and rigorous
acknowledgment is not a requirement.
YES
SESSION_TRANSACTED This is returned for transacted sessions if
the Session.getAcknowledgeMode
NO
51. Specifies whether the topic subscription is durable or
nondurable for an MDB listening on a topic.
Durable subscription on a topic provides guaranteed delivery
to the consumer for all the messages sent to the topic.
If the durable subscriber is not connected to a topic when a
message is received, MOM retains a copy of the message until
the subscriber connects and delivers the message.
@ActivationConfigProperty(
propertyName="destinationType",
propertyValue="javax.jms.Topic"),
@ActivationConfigProperty(
propertyName="subscriptionDurability",
propertyValue="Durable")
52. The messageSelector property is the MDB parallel to applying a
selector for a JMS consumer.
Messages retrieved can be filtered by using a message selector,
a criterion applied to the headers and properties of messages
specifying which messages the consumer wants to receive.
The selector syntax is identical to the WHERE clause in SQL, but
it uses message header and property names instead of column
names.
Selector expressions include literals, identifiers, whitespace,
expressions, standard brackets, logical and comparison
operators, arithmetic operators, and null comparisons.
@ActivationConfigProperty(
propertyName="messageSelector",
propertyValue="Fragile IS TRUE")
53. Type Description Example
Literals Can be strings, exact or approximate
numeric values, or booleans.
BidManagerMDB
100 TRUE
Identifiers Can be a message property or header
name; case sensitive.
RECIPIENT
NumOfBids Fragile
JMSTimestamp
Whitespace Same as defined in the Java language
specification: space, tab, form feed, and
line terminator.
Comparison
operators
Comparison operators, such as =, >, >=,
<=, <>.
RECIPIENT='BidManager
MDB‘ NumOfBids>=100
Logical
operators
All three types of logical operators—
NOT, AND, OR—are supported.
RECIPIENT='BidManager
MDB‘ AND
NumOfBids>=100
Null comparison IS NULL and IS NOT NULL comparisons. FirstName IS NOT NULL
True/false
comparison
IS [NOT] TRUE and IS [NOT] FALSE
comparisons.
Fragile IS TRUE
Fragile IS FALSE
54. Creates MDB instances and sets them up
Injects resources, including the message-driven
context
Places instances in a managed pool
Pulls an idle bean out of the pool when a message
arrives (the container may have to increase the pool
size at this point)
Executes the message listener method; e.g., the
onMessage method
When the onMessage method finishes executing,
pushes the idle bean back into the “method-ready”
pool
As needed, retires (or destroys) beans out of the pool
55.
56. The queue and the connection factory are injected by using the @Resource
annotation:
@Resource(name="jms/ShippingErrorQueue")
private javax.jms.Destination errorQueue;
@Resource(name="jms/QueueConnectionFactory")
private javax.jms.ConnectionFactory connectionFactory;
Then create and destroy a shared javax.jms.Connection instance using
lifecycle callbacks.
@PostConstruct
public void initialize() { connectionFactory.createConnection(); }
@PreDestroy
public void cleanup() { … }
Finally, the business method that sends the error message.
private void sendErrorMessage(ShippingError error) { … }
57. Choose the messaging models carefully: PTP or pub-sub
Remember modularization: Business logic should be decoupled and
modularized away from messaging-specific concerns.
Make good use of message filters: Multi purpose use of single
messaging destination.
Choose message types carefully: Using XML strings for messaging to
promote loose coupling between systems or using binary streams to
decrease the size of the message.
Be wary of poison messages: On runtime failure message processing,
the container is forced to roll back the transaction and put the
message back on the queue instead of acknowledging it, which are
called poison messages. It is avoided by setting up redelivery count
and dead message queue for the shipping poison messages as the
request destination,
Configure MDB pool size: Specifies the maximum number of
instances of a particular MDB the container can create.