FYI: Restartable Processes in Context of J2EE Re: [coyotos-dev]
Thoughts on (non)persistence
Constantine Plotnikov
cap at isg.axmor.com
Thu Feb 10 18:36:43 EST 2005
*Introduction*
This note is informational. It described approach to persistence of
processes for J2EE platform and what coyotos might borrow from it. The
note only considers EJB components. This note does not attempt to be
precise and complete; its purpose is just to convey a general idea. Some
shortcuts are taken in description. See J2EE specifications for more
details.
The notion of restartable application in J2EE is based on EJBs. The EJBs
are built to recover from crashes. Despite of over-complexity and insane
duplication of the functionality the J2EE model works somehow. So it
might be useful to examine it for both overall system layer and specific
application layer.
In EJB there is a distinction between component definition and component
deployment.
/Component Definition/
A component definition is a set of classes and metadata.
Classes specify code that works in the managed context and interfaces
used by other code. Metadata specifies additional semantics for the
methods and expectations of the component from the environment in which
it is executed.
There are usually three classes or interfaces associated with each EJB
component:
* Instance interface. This is an interface of the specific instance of
the component. Each instance has remove method.
* Home interface. This interface allows creating (for entity beans also
locate) instance the component.
* Implementation class. This class provides actual implementation of the
component logic. Note that transaction logic and some other parts of the
method semantics are implemented by container.
Example of additional semantics is a transaction attribute. Using this
attribute the component developer, for example, might specify that J2EE
server must start a new transaction when the method is invoked or method
requires already started transaction to execute.
Requirements of component are specified in terms of what component
should be able to see on the local naming context.
The naming context might contain three kinds of objects:
* Primitive values (strings, integers, etc.). These are used to
configure the components using administrative tools.
* Resource connectors. These are used to access external resources. For
example message queues, databases, etcs.
* Home interfaces of other EJBs.
/Component deployment/
It is possible to deploy one component definition several times on the
single application server. The J2EE application servers differ on how
extensive the support for this scenario is.
During deployment the application server creates mapping from names
expected in the naming context to resources that are available to the
application server. The different deployments of the same component may
have the same values or different values.
When the component instance is created, a new populated naming context
is created and given to instance.
*Component Kinds*
There are the following components kinds in EJB (they differ on their
semantics with respect to persistence).
* Stateless session beans
* Message-driven beans
* Entity beans
* Stateful session beans
/Sateless Session Beans/
These are components that do not have any state that should be
preserved. These components should be implemented as if they are
completely interchangeable. The only state they might have is objects
that are looked up form the component naming context. And even this is
just an allowed optimization.
Each request to such component must carry all information that is
required for request processing.
These components are often used to implement web services.
One of the valid implementations of theses component kind on the server
is the following. The server keeps a pool of created instances of this
component. When create method is called on home interface, nothing is
done. When method on facet object is invoked, an free instance is
selected and method is invoked on it. When remove method is invoked
nothing is done.
Another valid but hopelessly inefficient implementation is to create an
instance of the object for each method invocation then to remove
instance. The problem with this implementation is that lookup from
naming context is too inefficient in J2EE. Partially because naming
context is accessed statically rather than through component context
object (which exists for all EJBs) and an application server must to a
lot of unneeded work.
Because the component does not have state of this own and all instances
are completely interchangeable, there is no problem with server restart
for this type of the component.
/Message driven bean/
Basically this is cut down version of stateless session beans that have
only one method "onMessage" which is executed when event is received
from some message queue. Because there is only one method with fixed
name that is never called by clients of the component (they invoke this
componet by sending message to the message queue), there is no need for
home interface and instance interface.
/Stateful Session Beans/
These components do have state but they might die at any moment. They
might be either removed explicitly or by timeout (if it have not been
used for some time). A server crush usually also kills them, however
some servers provide limited recovery logic. The client application must
be ready to recreate instance of stateful session bean at any time.
This component type is least used in real applications. One of few
usages of it is keeping some session state for servlets. The component
restriction means that the instances might be references only from other
stateful session beans or from HTTP sessions.
/Entity Beans/
These components provide access to data stored in some database. Each
instance is a view of some database entity (or of similar persistent
information store). Only transactional access to entity beans is allowed.
The entity beans might have bean managed persistence or container
managed persistence. I will consider only container managed persistence
below.
Entity beans might refer other entity beans. However home interfaces of
referred entity beans must be declared in deployment descriptor. When
the container stores entity bean to database, it converts references to
the correct field updates. The information which deployment of referred
entity bean was used is specified during deployment. Therefore the
container knows how to store references.
When non entity bean component needs to obtain reference to entity bean,
it either creates new entity or executes finder method on home interface
to locate an existing entity.
There are no problems on server restart. An entity bean is just runtime
view of persistent entity. If runtime view is gone, the entity still
lives in persistent storage.
*J2EE Application Clients*
J2EE also supports client application model. The client Java application
might also specify its requirements. The application server generate
mapping file for the java application. The application client uses
mapping file and externally visible directory service (for example LDAP)
to locate references to EJB home interfaces.
I do not have an experience with using J2EE application clients in real
applications.
*What are possible lessons for coyotos?*
A solution does not have to be suitable for any process. Like not every
Java class is a valid J2EE component. We might put additional
restrictions on the processes that should recover.
Solution to problem how to distinguish different instances of the same
process instance is simple. We should distinguish between deployment and
definition. The definition is a process image possibly with some
additional metadata. The deployment is definition plus context
definition. When instance starts, it is given a context object. The
instance resolves references to external services through this context
object.
I also suggest using some other term for such processes. Windows uses
word "service". So we have a "service definition", "deployed service",
"different deployments of service", "inter-service object references",
"service process" etc.
I think that it is also nicely matches capability ideology. At least it
is better than process instance authentication.
The context for example might be a some folder in file system where
service runtime mounts references to other services before starting the
service or during start of the service. To allow cyclic references the
service process must not consider there references valid before some
method is called, however it should provide its analog of EJB home
interfaces to the service runtime. Or there might be some lazy service
instantiation scenario.
Service might correspond to entity bean or stateless session bean.
Normal application seems to correspond to session beans. The one
operation processes like grep are similar to stateless and GUI
applications are similar to statefull. The processes that refer to
objects in normal applications should be also a normal application. The
references might be kept on some mount points to simplify discovery.
ActiveX components in Windows also correspond to stateful session beans.
More information about the coyotos-dev
mailing list