Vous êtes sur la page 1sur 29

Professional Open Source™

The Server Side


EJB Container Walkthrough

© JBoss, Inc. 2003-2005. 8/2/2005 1

Topics
Professional Open Source™

Creation of the invocation object on the server side


– Handling the incoming payload

Invoker implementations
– RMI/JRMP Invoker

Server side interceptor implementations


– Security Interceptor
– Transaction Interceptor
– Lock Interceptor
– Instance Interceptor
– Synchronization Interceptor

© JBoss, Inc. 2003-2005. 2

1
JBoss and Detached Invokers
Professional Open Source™

– The proxy is connected to an invoker instance


– The invoker lets the microkernel route the invocation
Server JVM
EJB Container MBean

Port 1234
RemoteInvoker
RemoteInvoker

JMX
JMX Microkernel
Client JVM
EJB Container MBean
Typed

Microkernel
Interface Invocation

011101010101
Client
Client RemoteInvoker
RemoteInvoker
Port 4321
Service MBean
Client Proxy

© JBoss, Inc. 2003-2005. 3

Server Side Creation of Invocation


Professional Open Source™

An invoker talks to the microkernel


– The invocation is routed in the kernel
– The kernel is not concerned with the component type or interface
org.jboss.proxy.Interceptor
org.jboss.proxy.Interceptor org.jboss.invocation.
org.jboss.invocation.Invoker
Invoker org.jboss.mx.Interceptor
org.jboss.mx.Interceptor
Object
Objectinvoke(Invocation
invoke(Invocationmi)
mi) Object
Objectinvoke(Invocation
invoke(Invocationmi)
mi) Object
Objectinvoke(Invocation
invoke(Invocationmi)
mi)

Client JVM
Microkernel
Microkernel

01010110101001
Client
Client Invoker
Invoker

java.lang.reflect.InvocationHandler
java.lang.reflect.InvocationHandler javax.management.MBeanServer
javax.management.MBeanServer
Object Object
Objectinvoke(
invoke( ObjectName
ObjectNamename,
name,String
StringoperationName,
Objectinvoke(Object
invoke(Objectproxy,
proxy,Method
Methodmethod,
method,Object[]
Object[]args)
args) operationName,
Object[]
Object[]params,
params,String[]
String[]signature)
signature)

From the client to the server we work on a detyped invocation chain


© JBoss, Inc. 2003-2005. 4

2
The Message
Professional Open Source™

Interceptor approach works because we work on a detyped invoke


signature
– The interceptors do not need to know about the interface/client
– Interceptors can be built without knowledge of deployment environment
– Each works on a type that is independent of the target type

JBoss is based internally on the “Chain of Responsibility” design


pattern
– Implementation is in the Invocation class
– Describes the method invocation the client makes

© JBoss, Inc. 2003-2005. 5

Interceptors
Professional Open Source™

The interceptors associated with a container form a linked-list


structure through which Invocation objects pass
– first interceptor in the chain is invoked when an Invoker passes an
Invocation to the container
– The last interceptor invokes the business method on the bean

Advantages of an interceptor pattern include


– Flexibility in the arrangement of interceptors
– Clear functional distinction between different interceptors.
• e.g., logic for transaction and security is cleanly separated between
the TXInterceptor and SecurityInterceptor

If any of the interceptors fail, the call is terminated at that point.


– This is a fail-quickly type of semantic
– For example, if a secured EJB is accessed without proper permissions,
the call will fail right away (transactions and caches are not accessed)

© JBoss, Inc. 2003-2005. 6

3
Distributed Invokers
Professional Open Source™

A
A invoker
invoker extends
extends Remote
Remote
package
packageorg.jboss.invocation;
org.jboss.invocation; Even
Even ifif the
the implementation
implementation
is
is local
local
public
publicinterface
interfaceInvoker
Invokerextends
extendsRemote
Remote{{

/**
/**
**TheTheinvoke
invokewith
withan
anInvocation
InvocationObject
Object
**thethedelegate
delegatecan
canhandle
handlenetwork
networkprotocols
protocolsononbehalf
behalfofofproxies
proxies(proxies
(proxiesdelegate
delegatetotothese
thesepuppies)
puppies)
** We Weprovide
providedefault
defaultimplemenations
implemenationswith withJRMP/Local/Clustered
JRMP/Local/Clusteredinvokers.
invokers.
** TheThedelegates
delegatesare
arenot
nottied
tiedtotoaatype
typeofofinvocation
invocation(EJB
(EJBororgeneric
genericRMI).
RMI).
**
**@param
@paraminvocation
invocation AApointer
pointertotothetheinvocation
invocationobject
object
**
**@return
@return Return
Returnvalue
valueofofmethod
methodinvocation.
invocation.
**
**@throws
@throwsException
Exception Failed
Failedtotoinvoke
invokemethod.
method.
*/*/
public
publicObject
Objectinvoke(Invocation
invoke(Invocationinvocation)
invocation) throws
throwsException;
Exception;
}}

© JBoss, Inc. 2003-2005. 7

JRMPInvoker (1/2)
Professional Open Source™

org.jboss.invocation.jrmp.server.JRMPInvoker
org.jboss.invocation.jrmp.server.JRMPInvoker
/**
/**
**TheTheJRMPInvoker
JRMPInvokerisisananRMI
RMIimplementation
implementationthat
thatcan
cangenerate
generateInvocations
Invocations
**from
fromRMI/JRMP
RMI/JRMPinto
intothe
theJMX
JMXbase.
base.
*/*/
public
publicclass
classJRMPInvoker
JRMPInvokerextends
extendsRemoteServer
RemoteServer
implements
implementsInvoker,
Invoker,JRMPInvokerMBean,
JRMPInvokerMBean, MBeanRegistration
MBeanRegistration{{

/**
/**An
Anoptional
optionalcustom
customclient
clientsocket
socketfactory
factory*/*/
protected
protectedRMIClientSocketFactory
RMIClientSocketFactoryclientSocketFactory;
clientSocketFactory;
/**
/**An
Anoptional
optionalcustom
customserver
serversocket
socketfactory
factory*/*/
protected
protectedRMIServerSocketFactory
RMIServerSocketFactoryserverSocketFactory;
serverSocketFactory;
/**
/**The
Theclass
classname
nameofofthe
theoptional
optionalcustom
customclient
clientsocket
socketfactory
factory*/*/
protected
protectedString
StringclientSocketFactoryName;
clientSocketFactoryName;
/**
/**The
Theclass
classname
nameofofthe
theoptional
optionalcustom
customserver
serversocket
socketfactory
factory*/*/
protected
protectedString
StringserverSocketFactoryName;
serverSocketFactoryName;
/**
/**The
Theaddress
addresstotobind
bindthe
thermi
rmiport
porton
on*/*/
protected
protectedString
StringserverAddress;
serverAddress;
/**
/**The
Thename
nameofofthe
thesecurity
securitydomain
domaintotouse
usewith
withserver
serversockets
socketsthat
thatsupport
supportSSL
SSL*/*/
protected
protectedString
StringsslDomain;
sslDomain;

© JBoss, Inc. 2003-2005. 8

4
JRMPInvoker (2/2)
Professional Open Source™

org.jboss.invocation.jrmp.server.JRMPInvoker
org.jboss.invocation.jrmp.server.JRMPInvoker
/**
/**
**Invoke
InvokeaaRemote
Remoteinterface
interfacemethod.
method.
*/*/
public
publicObject
Objectinvoke(Invocation
invoke(Invocationinvocation)
invocation)throws
throwsException
Exception{{
ClassLoader
ClassLoaderoldCl
oldCl==Thread.currentThread().getContextClassLoader();
Thread.currentThread().getContextClassLoader();
ObjectName
ObjectNamembean
mbean==null;
null;

try
try{{
////Deserialize
Deserializethe
thetransaction
transactionififititis
isthere
there
MarshalledInvocation
MarshalledInvocationmi mi==(MarshalledInvocation)
(MarshalledInvocation)invocation;
invocation;
Invocation
Invocation object
invocation.setTransaction(importTPC(mi.getTransactionPropagationContext()));
invocation.setTransaction(importTPC(mi.getTransactionPropagationContext())); object carries
carries the
the
target
target name
name (JMX
(JMX
mbean
mbean==(ObjectName)
(ObjectName)Registry.lookup(invocation.getObjectName());
Registry.lookup(invocation.getObjectName()); ObjectName)
ObjectName)
////The
Thecl
clon
onthe
thethread
threadshould
shouldbe
beset
setin
inanother
anotherinterceptor
interceptor
Object
Objectobj
obj==support.getServer().invoke(mbean,
support.getServer().invoke(mbean,"invoke",
"invoke",
new Object[] {invocation}, Send
new Object[] {invocation}, Send thethe invocation
invocation to
to
Invocation.INVOKE_SIGNATURE); the
Invocation.INVOKE_SIGNATURE); the target
target through
through the
the
return
returnnew
newMarshalledObject(obj);
MarshalledObject(obj); microkernel.
microkernel.
}} finally {
finally {
currentThread.setContextClassLoader(oldCl);
currentThread.setContextClassLoader(oldCl);
}}

© JBoss, Inc. 2003-2005. 9

Adding Remoteness to Any MBean


Professional Open Source™

Any MBean can expose an interface for remote invocations using proxy
factory services

JBoss has RMI/HTTP and RMP/JRMP proxy factories


– org.jboss.invocation.http.server.HttpProxyFactory
– org.jboss.invocation.jrmp.server.JRMPProxyFactory
– Both allow for custom client proxy interceptor stacks

You can easily add your own proxy factories following the pattern illustrated in
these two services

Works with both Standard MBeans and XMBeans


– Standard MBeans require the addition of an invoke(Invocation) management
operation
– XMBeans can either add an invoke(Invocation) management operation at the bean
level or use a custom interceptor
– Only XMBeans easily support customization of the server interceptor stack

© JBoss, Inc. 2003-2005. 10

5
JRMPProxyFactory
Professional Open Source™

A general service for exposing a proxy RPC interface for any MBean
over any transport.
– Has nothing to do with RMI/JRMP, just a historic name

Main service attributes:


– InvokerName: the detached invoker mbean service that handles the
transport.
– TargetName
– JndiName
– ExportedInterfaces
– ClientInterceptors

Based on the detached invoker service exposing its transport Invoker


proxy through the org.jboss.system.Registry under its service name.

© JBoss, Inc. 2003-2005. 11

JRMPProxyFactoryMBean
Professional Open Source™

org.jboss.invocation.jrmp.server.
org.jboss.invocation.jrmp.server.JRMPProxyFactoryMBean
JRMPProxyFactoryMBean
public
publicinterface
interfaceJRMPProxyFactoryMBean
JRMPProxyFactoryMBeanextends
extendsServiceMBean
ServiceMBean Detached
Detached invoker
invoker service
service
{{
handling
handling transport
transport
public
publicObjectName
ObjectNamegetInvokerName();
getInvokerName();
public
publicvoid
voidsetInvokerName(ObjectName
setInvokerName(ObjectNamejmxInvokerName);
jmxInvokerName);

public
publicObjectName
ObjectNamegetTargetName();
getTargetName(); Target
Target MBean
MBean
public
publicvoid
voidsetTargetName(ObjectName
setTargetName(ObjectNametargetName);
targetName); invocations
invocations will
will be
be
dispatched
dispatched to
to
public
publicString
StringgetJndiName();
getJndiName();
public
publicvoid
voidsetJndiName(String
setJndiName(StringjndiName);
jndiName);

public
publicClass[]
Class[]getExportedInterfaces();
getExportedInterfaces(); RPC
RPC interfaces
interfaces client
client
public
publicvoid
voidsetExportedInterfaces(Class[]
setExportedInterfaces(Class[]exportedInterface);
exportedInterface); will
will see
see
public
publicElement
ElementgetClientInterceptors();
getClientInterceptors();
public
publicvoid
voidsetClientInterceptors(Element
setClientInterceptors(Elementconfig)
config)throws
throwsException;
Exception;

public
publicObject
ObjectgetProxy();
getProxy(); Client
Client proxy
proxy interceptor
interceptor
}} stack
stack

© JBoss, Inc. 2003-2005. 12

6
JRMPProxyFactory Example
Professional Open Source™

<!--
<!--The
TheJRMP
JRMPinvoker
invokerproxy
proxyconfiguration
configurationfor
forthe
theInvokerAdaptorService
InvokerAdaptorService-->
-->
<mbean
<mbeancode="org.jboss.invocation.jrmp.server.JRMPProxyFactory"
code="org.jboss.invocation.jrmp.server.JRMPProxyFactory"
name="jboss.jmx:type=adaptor,name=Invoker,protocol=jrmp,service=proxyFactory">
name="jboss.jmx:type=adaptor,name=Invoker,protocol=jrmp,service=proxyFactory">
<!--
<!--Use
Usethe
thestandard
standardJRMPInvoker
JRMPInvokerfromfromconf/jboss-service.xml
conf/jboss-service.xml-->
-->
<depends
<dependsoptional-attribute-name="InvokerName">jboss:service=invoker,type=jrmp</depends>
optional-attribute-name="InvokerName">jboss:service=invoker,type=jrmp</depends>
<!--
<!-- The target MBean is the InvokerAdaptorService configured below-->
The target MBean is the InvokerAdaptorService configured below -->
<depends
<dependsoptional-attribute-name="TargetName">jboss.jmx:type=adaptor,name=Invoker</depends>
optional-attribute-name="TargetName">jboss.jmx:type=adaptor,name=Invoker</depends>
<!--
<!--Where
Whereto tobind
bindthe
theRMIAdaptor
RMIAdaptorproxy
proxy-->
-->
<attribute
<attributename="JndiName">jmx/invoker/RMIAdaptor</attribute>
name="JndiName">jmx/invoker/RMIAdaptor</attribute>
<!--
<!--The
TheRMI
RMIcompabitle
compabitleMBeanServer
MBeanServerinterface
interface-->
-->
<attribute
<attributename="ExportedInterfaces">org.jboss.jmx.adaptor.rmi.RMIAdaptor,
name="ExportedInterfaces">org.jboss.jmx.adaptor.rmi.RMIAdaptor,
org.jboss.jmx.adaptor.rmi.RMIAdaptorExt
org.jboss.jmx.adaptor.rmi.RMIAdaptorExt
</attribute>
</attribute>
<attribute
<attributename="ClientInterceptors">
name="ClientInterceptors">
<interceptors>
<interceptors>
<interceptor>org.jboss.proxy.ClientMethodInterceptor</interceptor>
<interceptor>org.jboss.proxy.ClientMethodInterceptor</interceptor>
<interceptor>org.jboss.proxy.SecurityInterceptor</interceptor>
<interceptor>org.jboss.proxy.SecurityInterceptor</interceptor>
<interceptor>org.jboss.jmx.connector.invoker.client.InvokerAdaptorClientInterceptor</interceptor>
<interceptor>org.jboss.jmx.connector.invoker.client.InvokerAdaptorClientInterceptor</interceptor>
<interceptor>org.jboss.invocation.InvokerInterceptor</interceptor>
<interceptor>org.jboss.invocation.InvokerInterceptor</interceptor>
</interceptors>
</interceptors>
</attribute>
</attribute>
</mbean>
</mbean>

© JBoss, Inc. 2003-2005. 13

Interceptor
Professional Open Source™

org.jboss.ejb.Interceptor
org.jboss.ejb.Interceptor

public
publicinterface
interfaceInterceptor
Interceptorextends
extendsContainerPlugin
ContainerPlugin
{{
public
publicvoid
voidsetNext(Interceptor
setNext(Interceptorinterceptor);
interceptor);
public
publicInterceptor
InterceptorgetNext();
getNext();

public
publicObject
ObjectinvokeHome(Invocation
invokeHome(Invocationmi)
mi)throws
throwsException;
Exception;
public
publicObject
Objectinvoke(Invocation
invoke(Invocationmi)
mi)throws
throwsException;
Exception;
}}
Each
Each implements
implements Interceptor
Interceptor
Synchronization
Transaction

Synchronization
Connection
Transaction

Connection

Relation
Security

Relation
Security

Cache
Cache
Lock
Lock

Call
Call

© JBoss, Inc. 2003-2005. 14

7
Interceptors
Professional Open Source™

Configure per bean


– Each bean comes with it’s own jboss.xml file and configuration
– The server has a different personality for all servers deployed
– Ex: stand-alone server, embedded application

Synchronization
Transaction

Synchronization
Connection
Transaction

Connection

Relation
Security

Includes all

Relation
Security

Cache
Cache
Lock
Lock

Call
Call
transactional
and persistence
Transaction
Transaction
Security
Security

No
Cache
Cache
Lock
Lock

Call
Call
persistence

© JBoss, Inc. 2003-2005. 15

Interceptors
Professional Open Source™

The “in and out” mapping to “try-finally”


– In maps to a “try”
• All the interceptor code on the way in is done
• The next interceptor is invoked before the call returns
– Out maps to a “finally”
• On the way back up in the interceptor stack we go through the finally
blocks
– Readable code with separated in and out blocks

© JBoss, Inc. 2003-2005. 16

8
Specifying the Interceptor Stack
Professional Open Source™

standardjboss.xml
standardjboss.xml or
orjboss.xml
jboss.xml
<jboss>
<jboss>
<enforce-ejb-restrictions>false</enforce-ejb-restrictions>
<enforce-ejb-restrictions>false</enforce-ejb-restrictions>
<container-configurations>
<container-configurations>

<container-configuration>
<container-configuration>
<container-name>Standard
<container-name>StandardCMP CMP2.x
2.xEntityBean</container-name>
EntityBean</container-name>
<call-logging>false</call-logging>
<call-logging>false</call-logging>
<container-invoker>org.jboss.proxy.ejb.ProxyFactory</container-invoker>
<container-invoker>org.jboss.proxy.ejb.ProxyFactory</container-invoker>
<container-interceptors>
<container-interceptors>
<interceptor>org.jboss.ejb.plugins.LogInterceptor</interceptor>
<interceptor>org.jboss.ejb.plugins.LogInterceptor</interceptor>
<interceptor>org.jboss.ejb.plugins.SecurityInterceptor</interceptor>
<interceptor>org.jboss.ejb.plugins.SecurityInterceptor</interceptor>
<interceptor>org.jboss.ejb.plugins.TxInterceptorCMT</interceptor>
<interceptor>org.jboss.ejb.plugins.TxInterceptorCMT</interceptor>
<interceptor
<interceptormetricsEnabled="true">org.jboss.ejb.plugins.MetricsInterceptor</interceptor>
metricsEnabled="true">org.jboss.ejb.plugins.MetricsInterceptor</interceptor>
<interceptor>org.jboss.ejb.plugins.EntityCreationInterceptor</interceptor>
<interceptor>org.jboss.ejb.plugins.EntityCreationInterceptor</interceptor>
<interceptor>org.jboss.ejb.plugins.EntityLockInterceptor</interceptor>
<interceptor>org.jboss.ejb.plugins.EntityLockInterceptor</interceptor>
<interceptor>org.jboss.ejb.plugins.EntityInstanceInterceptor</interceptor>
<interceptor>org.jboss.ejb.plugins.EntityInstanceInterceptor</interceptor>
<interceptor>org.jboss.resource.connectionmanager.CachedConnectionInterceptor</interceptor>
<interceptor>org.jboss.resource.connectionmanager.CachedConnectionInterceptor</interceptor>
<interceptor>org.jboss.ejb.plugins.EntitySynchronizationInterceptor</interceptor>
<interceptor>org.jboss.ejb.plugins.EntitySynchronizationInterceptor</interceptor>
<interceptor>org.jboss.ejb.plugins.cmp.jdbc.JDBCRelationInterceptor</interceptor>
<interceptor>org.jboss.ejb.plugins.cmp.jdbc.JDBCRelationInterceptor</interceptor>
</container-interceptors>
</container-interceptors>

© JBoss, Inc. 2003-2005. 17

An EJB Container
Professional Open Source™

An EJB container is the sum of


Transaction
Transaction
– Interceptors Data
Data Source
Source Manager
Manager
– Plugins per container
– MBeans in the server
Microkernel
Microkernel

Bean
Bean CMP
CMP
Cache
Cache
Lock
Lock Engine
Engine
Synchronization
Transaction

Synchronization
Connection
Transaction

Connection
Security
Security

Cache
Cache
Lock
Lock

© JBoss, Inc. 2003-2005. 18

9
An Entity Bean Creation Walkthrough
Professional Open Source™

Deployment
– EJB Deployer
– Container configuration
– EJB home proxy creation and export

© JBoss, Inc. 2003-2005. 19

Deployment
Professional Open Source™

Put an EJB in the deploy file


– Thread picks it up
– Container Factory invoked
– Container stack is created using externalized configuration

Deployer Container
Factory

/deploy

© JBoss, Inc. 2003-2005. 20

10
Deployment
Professional Open Source™

And The home proxy is registered in JNDI


– home is available in JNDI under the EJB name
– jboss.xml was used to configure container and JNDI etc
– Done

Deployer Container
Factory Container

/deploy JNDI
HomeProxy

© JBoss, Inc. 2003-2005. 21

Log Interceptor
Professional Open Source™

1- Logging
– Log the call and what was in it
• The arguments
• The method name
Synchronization
Transaction

Synchronization
Connection
Transaction

Connection
Security
Security

Cache
Cache
Lock
Lock
Log

Call
Log

Call

Invocation

© JBoss, Inc. 2003-2005. 22

11
Security Interceptor
Professional Open Source™

2-Security
– Enforces J2EE declarative security
• Authentication
• Role-based permissions

Synchronization
Transaction

Synchronization
Connection
Transaction

Connection
Security
Security

Cache
Cache
Lock
Lock
Log

Call
Log

Call
Invocation

© JBoss, Inc. 2003-2005. 23

Security Interceptor
Professional Open Source™

org.jboss.ejb.plugins.SecurityInterceptor
org.jboss.ejb.plugins.SecurityInterceptor
/**
/**The
TheSecurityInterceptor
SecurityInterceptorisiswhere
wherethetheEJB
EJB2.0
2.0declarative
declarativesecurity
securitymodel
model
** isisenforced.
enforced.ThisThisisiswhere
wherethethecaller
calleridentity
identitypropagation
propagationisiscontrolled
controlledasaswell.
well.*/*/
public
publicclass classSecurityInterceptor
SecurityInterceptorextends
extendsAbstractInterceptor
AbstractInterceptor
{{
protected
protectedAuthenticationManager
AuthenticationManagersecurityManager;
securityManager;
protected
protectedRealmMapping
RealmMappingrealmMapping;
realmMapping;
protected Interfaces
Interfacesimplemented
implemented
protectedPrincipal
PrincipalrunAsRole;
runAsRole;
by
bythe
thesecurity
securitymanager.
manager.
public
publicvoid voidsetContainer(Container
setContainer(Containercontainer)
container)
{{
super.setContainer(container);
super.setContainer(container);
if(if(container
container!=!=null
null))
{{
BeanMetaData
BeanMetaDatabeanMetaData
beanMetaData==container.getBeanMetaData();
container.getBeanMetaData();
SecurityIdentityMetaData
SecurityIdentityMetaDatasecMetaData
secMetaData==beanMetaData.getSecurityIdentityMetaData();
beanMetaData.getSecurityIdentityMetaData();
if(
if(secMetaData
secMetaData!=!=nullnull&&
&&secMetaData.getUseCallerIdentity()
secMetaData.getUseCallerIdentity()== ==false
false))
{{
String
StringroleName
roleName==secMetaData.getRunAsRoleName();
secMetaData.getRunAsRoleName();
runAsRole
runAsRole==new newSimplePrincipal(roleName);
SimplePrincipal(roleName); Metadata
Metadataisis
}} retrieved
retrieved
securityManager
securityManager==container.getSecurityManager();
container.getSecurityManager(); from
fromthe
thecontainer.
container.
realmMapping
realmMapping==container.getRealmMapping();
container.getRealmMapping();
}}

© JBoss, Inc. 2003-2005. 24

12
Security Interceptor: Run-As
Professional Open Source™

org.jboss.ejb.plugins.SecurityInterceptor
org.jboss.ejb.plugins.SecurityInterceptor
public
publicObject
Objectinvoke(Invocation
invoke(Invocationmi)
mi)throws
throwsException
Exception
{{
////Authenticate
Authenticatethe
thesubject
subjectand
andapply
applyany
anydeclarative
declarativesecurity
securitychecks
checks
checkSecurityAssociation(mi,
checkSecurityAssociation(mi,false);
false);
Authentication
Authentication and
and authorization
authorization
/*/*IfIfaarun-as
run-asrole
rolewas
wasspecified,
specified,push
pushititso
sothat
thatany
anycalls
callsmade
made is
is done
done here.
here.
**by bythis
thisbean
beanwill
willhave
havethe
therunAsRole
runAsRoleavailable
availablefor
fordeclarative
declarative
**security
securitychecks.
checks.
*/*/
if(if(runAsRole
runAsRole!=!=null
null))
SecurityAssociation.pushRunAsRole(runAsRole);
SecurityAssociation.pushRunAsRole(runAsRole);

try
try{{
Object IfIf<run-as>
<run-as>element
elementhas
hasbeen
beenset,
set,
ObjectreturnValue
returnValue==getNext().invoke(mi);
getNext().invoke(mi);
return push
pushandandpop
popthe
therun-as
run-asrole
roleinto
into
returnreturnValue;
returnValue; thread
threadlocal.
local.
}}
finally
finally{{
if(
if(runAsRole
runAsRole!=!=null
null))
SecurityAssociation.popRunAsRole();
SecurityAssociation.popRunAsRole();
}}

© JBoss, Inc. 2003-2005. 25

Security Interceptor: Authentication


Professional Open Source™

org.jboss.ejb.plugins.SecurityInterceptor
org.jboss.ejb.plugins.SecurityInterceptor
/**
/**TheTheEJB EJB2.0
2.0declarative
declarativesecurity
securityalgorithm:
algorithm:
** 1.1.Authenticate
Authenticatethe thecaller
callerusing
usingthetheprincipal
principaland
andcredentials
credentialsininthe
theMethodInvocation
MethodInvocation
** 2.2.Validate
Validateaccess
accesstotothe
themethod
methodby bychecking
checkingthetheprincipal's
principal'sroles
rolesagainst
against
** those thoserequired
requiredtotoaccess
accessthethemethod.
method.
*/*/
private
privatevoid voidcheckSecurityAssociation(Invocation
checkSecurityAssociation(Invocationmi, mi,boolean
booleanhome)
home) throws
throwsException
Exception
{{
Principal
Principalprincipal
principal==mi.getPrincipal();
mi.getPrincipal(); The
TheInvocation
Invocationobject
object
Object
Objectcredential
credential==mi.getCredential();
mi.getCredential(); carries
carriesthe
thesecurity
securitycontext.
context.
////IfIfthere is no security manager then there is no authentication
there is no security manager then there is no authentication required required
ifif(securityManager
(securityManager== ==null)
null){{
////Allow
Allowfor
forthe
theprogatation
progatationofofcaller
callerinfo
infototoother
otherbeans
beans
SecurityAssociation.setPrincipal(
SecurityAssociation.setPrincipal(principal
principal););
SecurityAssociation.setCredential(
SecurityAssociation.setCredential(credential
credential););
return; Authentication
Authenticationcheck
check
return; using
}} usingsecurity
securitymanager
manager
(AuthenticationManager
(AuthenticationManager
////Check
Checkthe thesecurity
securityinfo
infofrom
fromthe
themethod
methodinvocation
invocation interface).
interface).
ifif(securityManager.isValid(principal,
(securityManager.isValid(principal,credential)
credential)====false)
false) {{
SecurityException e = new SecurityException(msg);
SecurityException e = new SecurityException(msg);
throw
thrownewnewRemoteException("checkSecurityAssociation",
RemoteException("checkSecurityAssociation",e); e);
}…}…

© JBoss, Inc. 2003-2005. 26

13
Security Interceptor: Authorization
Professional Open Source™

org.jboss.ejb.plugins.SecurityInterceptor
org.jboss.ejb.plugins.SecurityInterceptor
......
/*/*IfIfthe
themethod
methodhas hasno
noassigned
assignedroles
rolesororthe
theuser
userdoes
doesnot
nothave
haveatat
least
leastone oneofofthe
theroles
rolesthen
thenaccess
accessisisdenied.
denied.*/*/
else
elseifif(realmMapping.doesUserHaveRole(principal,
(realmMapping.doesUserHaveRole(principal,methodRoles)
methodRoles)== ==false
false))
{{
String
Stringmethod
method==mi.getMethod().getName();
mi.getMethod().getName();
Set
SetuserRoles
userRoles==realmMapping.getUserRoles(principal);
realmMapping.getUserRoles(principal); Authorization.
Authorization.
String
Stringmsgmsg=="Insufficient
"Insufficientmethod
methodpermissions,
permissions,principal="+principal
principal="+principal
++",",method="+method+",
method="+method+",interface="+iface
interface="+iface
++",",requiredRoles="+methodRoles+",
requiredRoles="+methodRoles+",principalRoles="+userRoles;
principalRoles="+userRoles;
log.error(msg);
log.error(msg);
SecurityException e = new SecurityException(msg);
SecurityException e = new SecurityException(msg);
throw
thrownew newEJBException("checkSecurityAssociation",
EJBException("checkSecurityAssociation",e); e);
}}
}}

© JBoss, Inc. 2003-2005. 27

Transaction Interceptor
Professional Open Source™

3- Transaction (CMT)
– Does the methodA require a Tx?
– If so start one, if not maybe suspend it
Synchronization
Transaction

Synchronization
Connection
Transaction

Connection
Security
Security

Cache
Cache
Lock
Lock
Log

Call
Log

Call

Invocation

© JBoss, Inc. 2003-2005. 28

14
TXInterceptorCMT: Deadlock Recovery (1/5)
Professional Open Source™

org.jboss.ejb.plugins.TXInterceptorCMT
org.jboss.ejb.plugins.TXInterceptorCMT
public
publicclass
classTxInterceptorCMT
TxInterceptorCMTextends
extendsAbstractTxInterceptor
AbstractTxInterceptor{{

public
publicstatic
staticint
intMAX_RETRIES
MAX_RETRIES==5;5;

/**
/**
** This
Thismethod
methoddoes
doesinvocation
invocationinterpositioning
interpositioningofoftxtxmanagement
management
*/*/
public
publicObject
Objectinvoke(Invocation
invoke(Invocationinvocation)
invocation)throws
throwsException
Exception{{

Transaction Handles
Handles the
the declarative
declarative
oldTransaction==invocation.getTransaction();
TransactionoldTransaction invocation.getTransaction(); transaction
transaction attributes
attributes from
from
for ejb-jar.xml
ejb-jar.xml (next
(next slides)
slides)
for(int
(inti i==0;0;i i<<MAX_RETRIES;
MAX_RETRIES;i++) i++){{
try
try {{
return
returnrunWithTransactions(invocation);
runWithTransactions(invocation);
}}
catch
catch(Exception
(Exceptionex)
ex){{
ApplicationDeadlockException
ApplicationDeadlockExceptiondeadlock deadlock==ApplicationDeadlockException.isADE(ex);
ApplicationDeadlockException.isADE(ex);
ifif(deadlock
(deadlock!=!=null)
null){{
ifif(!deadlock.retryable()
(!deadlock.retryable()||||oldTransaction
oldTransaction!=!=null
null||||i i++11>=
>=MAX_RETRIES)
MAX_RETRIES)throw
throw
deadlock;
deadlock; Application
Application deadlock
deadlock detection
detection
Thread.sleep(random.nextInt(1
Thread.sleep(random.nextInt(1++i),i),random.nextInt(1000));
random.nextInt(1000)); will
will attempt
attempt to
to re-execute
re-execute the
the
}}
invocation
invocation for
for aa possible
possible
else { throw
else { throw ex; }ex; }
resolution
resolution of
of resource
resource
allocation
allocation ordering
ordering problems.
problems.

© JBoss, Inc. 2003-2005. 29

TXInterceptorCMT (2/5)
Professional Open Source™

org.jboss.ejb.plugins.TXInterceptorCMT
org.jboss.ejb.plugins.TXInterceptorCMT
private
privateObject
ObjectrunWithTransactions(boolean
runWithTransactions(booleanremoteInvocation,
remoteInvocation,Invocation
Invocationmi)
mi)throws
throwsException
Exception
{{
////Old
Oldtransaction
transactionisisthe
thetransaction
transactionthat
thatcomes
comeswith
withthe
theMI
MI
Transaction
TransactionoldTransaction
oldTransaction==mi.getTransaction();
mi.getTransaction();
////New
Newtransaction
transactionisisthe
thenew
newtransaction
transactionthis
thismight
mightstart
start
Transaction
TransactionnewTransaction
newTransaction==null;
null;

InvocationType
InvocationTypetype
type==invocation.getType();
invocation.getType();
byte
bytetransType
transType==getTransactionMethod(invocation.getMethod(),
getTransactionMethod(invocation.getMethod(),type);
type);

////Thread
Threadarriving
arrivingmust
mustbebeclean
clean(jboss
(jbossdoesn't
doesn'tset
setthe
thethread
thread
////previously).
previously).However
Howeveroptimized
optimizedcalls
callscome
comewith
withassociated
associated
////thread
threadfor
forexample.
example.We Wesuspend
suspendthe thethread
threadassociation
associationhere,
here,and
and
////resume
resumeininthe
thefinally
finallyblock
blockofofthe
thefollowing
followingtry.
try.
Transaction
TransactionthreadTx
threadTx==tm.suspend();
tm.suspend();
Transtype
Transtypeisisthe
the
try declarative
try{{ declarative
switch transactional
transactionaltag
tag
switch(transType)
(transType)
{{

© JBoss, Inc. 2003-2005. 30

15
TXInterceptorCMT (3/5)
Professional Open Source™

org.jboss.ejb.plugins.TXInterceptorCMT
org.jboss.ejb.plugins.TXInterceptorCMT
case
caseMetaData.TX_NOT_SUPPORTED:
MetaData.TX_NOT_SUPPORTED:
////Do
Donot
notset
setaatransaction
transactionon
onthe
thethread
threadeven
evenififin
inMI,
MI,just
justrun
run
return
returninvokeNext(remoteInvocation,
invokeNext(remoteInvocation,mi,mi,false);
false);

case
caseMetaData.TX_REQUIRED:
MetaData.TX_REQUIRED:
ifif(oldTransaction
(oldTransaction==
==null)
null) {{ ////No
Notxtxrunning
running
tm.begin();
tm.begin(); ////Create
Createtxtx
newTransaction
newTransaction==tm.getTransaction();
tm.getTransaction(); ////Get
Getthe
thetxtx

mi.setTransaction(newTransaction);
mi.setTransaction(newTransaction); ////Let
Letthe
themethod
methodinvocation
invocationknow
know
}}
else
else{{ ////We
Wehave
haveaatxtxpropagated
propagated
tm.resume(oldTransaction);
tm.resume(oldTransaction); ////Associate
Associateititwith
withthe
thethread
thread
}}

try
try {{ ////Continue
Continueinvocation
invocation
return
returninvokeNext(remoteInvocation,
invokeNext(remoteInvocation,mi,
mi,newTransaction
newTransaction!= !=null);
null);
}}
finally
finally {{
ifif(newTransaction
(newTransaction!=!=null)
null) {{ ////Only
Onlydo
dosomething
somethingififwe
westarted
startedthe
thetransaction
transaction
endTransaction(invocation,
endTransaction(invocation,newTransaction,
newTransaction,oldTransaction);
oldTransaction);
}}
else{{tm.suspend();
else tm.suspend();}}

© JBoss, Inc. 2003-2005. 31

TXInterceptorCMT (4/5)
Professional Open Source™

org.jboss.ejb.plugins.TXInterceptorCMT
org.jboss.ejb.plugins.TXInterceptorCMT
case
caseMetaData.TX_SUPPORTS:
MetaData.TX_SUPPORTS:
{{
////Associate
Associateold
oldtransaction
transactionwith
withthe
thethread
thread
////Some
SomeTMs
TMscannot
cannotresume
resumeaanull
nulltransaction
transactionand andwill
willthrow
throw
////an
anexception
exception(e.g.
(e.g.Tyrex),
Tyrex),so
somake
makesure
sureititisisnot
notnull
null
ifif(oldTransaction
(oldTransaction!=!=null)
null)
tm.resume(oldTransaction);
tm.resume(oldTransaction);

try
try
{{
return
returninvokeNext(remoteInvocation,
invokeNext(remoteInvocation,mi,
mi,false);
false);
}}
finally
finally
{{
tm.suspend();
tm.suspend();
}}

////Even
Evenon
onerror
errorwe
wedon't
don'tdo
doanything
anythingwith
withthe
thetx,
tx,we
wedidn't
didn'tstart
startitit
}}

© JBoss, Inc. 2003-2005. 32

16
TXInterceptorCMT (5/5)
Professional Open Source™

org.jboss.ejb.plugins.TXInterceptorCMT
org.jboss.ejb.plugins.TXInterceptorCMT
case
caseMetaData.TX_REQUIRES_NEW:
MetaData.TX_REQUIRES_NEW:
{{
tm.begin();
tm.begin(); ////Always
Alwaysbegin
beginaatransaction
transaction
newTransaction
newTransaction==tm.getTransaction();
tm.getTransaction(); ////Get
Getitit
mi.setTransaction(newTransaction);
mi.setTransaction(newTransaction); ////Set
Setititon
onthe
themethod
methodinvocation
invocation

try
try {{ ////Continue
Continueinvocation
invocation
return
returninvokeNext(remoteInvocation,
invokeNext(remoteInvocation,mi, mi,true);
true);
}}
finally
finally {{
////We
Westarted
startedthe
thetransaction
transactionfor
forsure
sureso
sowe
wecommit
commitororroll
rollback
back
endTransaction(invocation,
endTransaction(invocation,newTransaction,
newTransaction,oldTransaction);
oldTransaction);
}}


}}
finally
finally
{{
////IN
INcase
casewe
wehad
hadaaTx Txassociated
associatedwith
withthe
thethread
threadreassociate
reassociate
ifif(threadTx
(threadTx!=!=null)
null)
tm.resume(threadTx);
tm.resume(threadTx);
}}

© JBoss, Inc. 2003-2005. 33

Lock Interceptor
Professional Open Source™

4 - Instance Locking
– Lock the method and handle transaction synchronization
• Pessimistic locking

STOP
STOP
Synchronization
Transaction

Synchronization
Connection
Transaction

Connection
Security
Security

Cache
Cache
Lock
Lock
Log

Call
Log

Call

Invocation

© JBoss, Inc. 2003-2005. 34

17
Locking
Professional Open Source™

Locking is required to enforce the EJB semantics a bean developer expects


– Only one thread is active in a bean instance
– Only one transaction is actively associated with the bean instance

Support for externalization of the locking policy implementation is handled by


two classes
– org.jboss.ejb.BeanLockManager
– org.jboss.ejb.BeanLock
• BeanLock is what you can change
• org.jboss.ejb.plugins.lock.BeanLockSupport is an abstract BeanLock
implementation helper class

Still quite complicated to do


– Locking is used from multiple interceptors and related objects
– Difficult to devise a new policy implementation without understanding all of the
parties involved

GREAT GAIN, GREAT DANGER, CALL THE EXPERTS!

© JBoss, Inc. 2003-2005. 35

BeanLockManager
Professional Open Source™

Basically just a map for BeanLocks


– Externalizes the type of BeanLock implementation
– The get lock operation will create a BeanLock if one does not exist for the
given key
– The get operation increments the BeanLock reference count
– The remove operation decrements the BeanLock reference count
• When reference count is mapping between lock and key is removed
– Has method reentrancy flag
• Are methods reentrant for the associated bean (Entity only)
– Has transaction synchronization timeout
• How long will a call wait for the associated transaction to be
scheduled

© JBoss, Inc. 2003-2005. 36

18
BeanLock Interface
Professional Open Source™

org.jboss.ejb.BeanLock
org.jboss.ejb.BeanLock
public
publicinterface
interfaceBeanLock
BeanLock
{{
public
publicObject
ObjectgetId();
getId();
public
publicvoid
voidsetId(Object
setId(Objectid);
id);
public
publicvoid
voidsetReentrant(boolean
setReentrant(booleanreentrant);
reentrant);
public
publicvoid
voidsetTimeout(int
setTimeout(inttimeout);
timeout);
public
publicvoid
voidsync();
sync();
public
publicvoid
voidreleaseSync();
releaseSync();
public
publicvoid
voidschedule(MethodInvocation
schedule(MethodInvocationmi) mi)throws
throwsException;
Exception;
public
publicvoid
voidsetTransaction(Transaction
setTransaction(Transactiontx);
tx);
public
publicTransaction
TransactiongetTransaction();
getTransaction();
public
publicvoid
voidendTransaction(Transaction
endTransaction(Transactiontx);tx);
public
publicvoid
voidwontSynchronize(Transaction
wontSynchronize(Transactiontx); tx);public
publicboolean
booleanisMethodLocked();
isMethodLocked();
public
publicint
intgetNumMethodLocks();
getNumMethodLocks();
public
publicvoid
voidaddMethodLock();
addMethodLock();
public
publicvoid
voidreleaseMethodLock();
releaseMethodLock();
public
publicvoid
voidaddRef();
addRef();
public
publicvoid
voidremoveRef();
removeRef();
public
publicint
intgetRefs();
getRefs();
}}

© JBoss, Inc. 2003-2005. 37

BeanLock Discussion
Professional Open Source™

The get/set ID methods


– BeanLocks have a key associated with them. This is set on creation by
the BeanLockManager

setReentrant
– Was the entity bean the BeanLockManager is associated with marked as
reentrant

setTimeout
– A transaction synchronization timeout in milliseconds

The sync/releaseSync acquire and release the lock mutex

The addRef/removeRef/getRefs methods


– Increment, decrement and access the lock reference count

© JBoss, Inc. 2003-2005. 38

19
BeanLock Discussion (Transactions)
Professional Open Source™

The get/set Transaction methods


– Get or sets the transaction that is active

endTransaction(Transaction tx)
– Signifies the end of the indicated transaction to the lock
– Called by the javax.transaction.Synchronization.afterCompletion method
for example

wontSynchronize(Transaction tx)
– Signifies that the transaction is not going to complete successfully
– Called during exception recovery

© JBoss, Inc. 2003-2005. 39

BeanLock Discussion (Call Serialization)


Professional Open Source™

The method lock related methods support serialization of threads


during method dispatch

The addMethodLock method


– Increments the active call count

The releaseMethodLock method


– Decrements the active call count

The isMethodLocked method


– Is the active call count > 0

The getNumMethodLocks method


– Get the count of active calls
– This should only be > 1 for reentrant beans

© JBoss, Inc. 2003-2005. 40

20
BeanLock Discussion (Scheduling)
Professional Open Source™

The schedule(MethodInvocation mi) method


– This is where the lock policy implementation resides
– When schedule returns successfully (no Exception)
• The calling thread must have exclusive access to the target bean
instance for the given method invocation
• The transaction associated with the thread must be the only
transaction the target bean instance is associated with

© JBoss, Inc. 2003-2005. 41

Scheduling Threads and Concurrency


Professional Open Source™

org.jboss.ejb.plugins.EntityLockInterceptor
org.jboss.ejb.plugins.EntityLockInterceptor
public
publicObject
Objectinvoke(Invocation
invoke(Invocationmi)
mi)throws
throwsException
Exception{{
////The
Thekey.
key.
Object
Objectkey
key==(CacheKey)
(CacheKey)mi.getId();
mi.getId();
////The
Thelock.
lock.
BeanLock
BeanLocklocklock;;

{{
lock
lock==(BeanLock)container.getLockManager().getLock(key);
(BeanLock)container.getLockManager().getLock(key);

lock.schedule(mi);
lock.schedule(mi);

try
try{{return
returngetNext().invoke(mi);
getNext().invoke(mi);}}

finally
finally {{
////we
weare
aredone
donewith
withthe
themethod,
method,decrease
decreasethe
thecount,
count,ififititreaches
reaches00ititwill
willwake
wakeup
up the
thenext
nextthread
thread
lock.sync();
lock.sync();
lock.releaseMethodLock();
lock.releaseMethodLock();
lock.releaseSync();
lock.releaseSync();
}}

© JBoss, Inc. 2003-2005. 42

21
EntityInstanceInterceptor
Professional Open Source™

5 - Instance Acquisition
– Is the instance corresponding to the PK in cache?
– If so then retrieve it
– If not go to the pools get one and cache it

Synchronization
Transaction

Synchronization
Connection
Transaction

Connection
Security
Security

Cache
Cache
Lock
Lock
Log

Call
Log

Call
Invocation

© JBoss, Inc. 2003-2005. 43

Entity Instance from Cache


Professional Open Source™

org.jboss.ejb.plugins.EntityInstanceInterceptor
org.jboss.ejb.plugins.EntityInstanceInterceptor
public
publicObject
Objectinvoke(Invocation
invoke(Invocationmi)
mi)throws
throwsException
Exception{{
This
This “context”
“context” isis the
the
wrapper
wrapper to
to the
the real
real
////The
Thekey
key instance
instance in in cache
cache
CacheKey
CacheKeykeykey==(CacheKey)
(CacheKey)mi.getId();
mi.getId();
////The context
The context
EntityEnterpriseContext
EntityEnterpriseContextctx
ctx==(EntityEnterpriseContext)
(EntityEnterpriseContext)container.getInstanceCache().get(key);
container.getInstanceCache().get(key);

////Associate
Associatetransaction,
transaction,ininthe
thenew
newdesign
designthe
thelock
lockalready
alreadyhas
hasthe
thetransaction
transactionfrom
fromtheprevious
thepreviousinterceptor
interceptor
ctx.setTransaction(mi.getTransaction());
ctx.setTransaction(mi.getTransaction());

////Set
Setthe
thecurrent
currentsecurity
securityinformation
information
ctx.setPrincipal(SecurityAssociation.getPrincipal());
ctx.setPrincipal(SecurityAssociation.getPrincipal());
////Set
Setcontext
contexton
onthe
themethod
methodinvocation
invocation
mi.setEnterpriseContext(ctx);
mi.setEnterpriseContext(ctx);

boolean
booleanexceptionThrown
exceptionThrown==false;
false;

try
try{{
return
returngetNext().invoke(mi);
getNext().invoke(mi);
}}

© JBoss, Inc. 2003-2005. 44

22
Synchronization Interceptor
Professional Open Source™

6 - Instance Synchronization
– The container knows to refresh the state
– Uses transaction synchronization callback and commit option to
synch DB
– Ensures state is “valid” , instance in memory is reflection of DB

Synchronization
Transaction

Synchronization
Connection
Transaction

Connection
Security
Security

Cache
Cache
Lock
Lock
Log
Log

Call
Call
Invocation

© JBoss, Inc. 2003-2005. 45

Entity State-DB Synchronization


Professional Open Source™

Loading the entity state from the datasource

org.jboss.ejb.plugins.EntitySynchronizationInterceptor
org.jboss.ejb.plugins.EntitySynchronizationInterceptor
public
publicObject
Objectinvoke(MethodInvocation
invoke(MethodInvocationmi) mi)throws
throwsException
Exception{{
////We
Weare
aregoing
goingtotowork
workwith
withthe
thecontext
contextaalot
lot
EntityEnterpriseContext
EntityEnterpriseContextctx
ctx==(EntityEnterpriseContext)mi.getEnterpriseContext();
(EntityEnterpriseContext)mi.getEnterpriseContext();

////The
TheTx
Txcoming
comingasaspart
partofofthe
theMethod
MethodInvocation
Invocation
Transaction
Transactiontxtx==mi.getTransaction();
mi.getTransaction();

////IsIsmy mystate
statevalid?
valid?
ifif(!ctx.isValid())
(!ctx.isValid()){{
////IfIfnot
nottell
tellthe
thepersistence
persistencemanager
managertotoload
loadthe
thestate
state
((EntityContainer)getContainer()).getPersistenceManager().loadEntity(ctx);
((EntityContainer)getContainer()).getPersistenceManager().loadEntity(ctx);

////Now
Nowthe
thestate
stateisisvalid
valid
ctx.setValid(true);
ctx.setValid(true);
}}

© JBoss, Inc. 2003-2005. 46

23
Container Interceptor
Professional Open Source™

Bean instance call dispatch


– Last interceptor in the chain is to call instance
– This is it!
• Tx is set
• State is ok
• Calls are synchronized

Synchronization
Transaction

Synchronization
Connection
Transaction

Connection
Security
Security

Cache
Cache
Lock
Lock
Log

Call
Log

Call
Invocation

© JBoss, Inc. 2003-2005. 47

ContainerInterceptor
Professional Open Source™

Container interceptor is implemented as an inner class within the container


implementation
org.jboss.ejb.EntityContainer$ContainerInterceptor
org.jboss.ejb.EntityContainer$ContainerInterceptor
////This
Thisisisthe
thelast
laststep
stepbefore
beforeinvocation
invocation--all
allinterceptors
interceptorsare
aredone
done
class
classContainerInterceptor
ContainerInterceptorimplements
implementsInterceptor
Interceptor
{{
…//
…//snip
snip
public
publicObject
Objectinvoke(MethodInvocation
invoke(MethodInvocationmi) mi)throws
throwsException
Exception{{
////Get
Getmethod
method
Method
Methodmm==(Method)beanMapping.get(mi.getMethod());
(Method)beanMapping.get(mi.getMethod());
Call
Call is
is fielded
fielded by
by
////Select the
the container
container
Selectinstance
instancetotoinvoke
invoke(container
(containeror
orbean)
bean)
ifif(m.getDeclaringClass().equals(EntityContainer.class))
(m.getDeclaringClass().equals(EntityContainer.class)){{
////Invoke
Invokeandandhandle
handleexceptions
exceptions
try
try
{{
return
returnm.invoke(EntityContainer.this,
m.invoke(EntityContainer.this,new newObject[]
Object[]{{mi
mi});
});
}}catch
catch(IllegalAccessException
(IllegalAccessExceptione)e){{
////Throw
Throwthis
thisas
asaabean
beanexception...(?)
exception...(?)
throw
thrownewnewEJBException(e);
EJBException(e);
…//
…//more morecatch
catch

© JBoss, Inc. 2003-2005. 48

24
ContainerInterceptor
Professional Open Source™

org.jboss.ejb.EntityContainer$ContainerInterceptor
org.jboss.ejb.EntityContainer$ContainerInterceptor
else
else{{
//wire
//wirethe
thetransaction
transactionon
onthe
thecontext,
context,this
thisisishow
howthe
theinstance
instanceremember
rememberthe
thetx
tx
ifif(mi.getEnterpriseContext().getTransaction()
(mi.getEnterpriseContext().getTransaction()====null)
null)
mi.getEnterpriseContext().setTransaction(mi.getTransaction());
mi.getEnterpriseContext().setTransaction(mi.getTransaction());

////Invoke
Invokeandandhandle
handleexceptions
exceptions
try
try
{{
return
returnm.invoke(mi.getEnterpriseContext().getInstance(),
m.invoke(mi.getEnterpriseContext().getInstance(),mi.getArguments());
mi.getArguments());
}}catch
catch(IllegalAccessException
(IllegalAccessExceptione) e){{
////Throw
Throwthis
thisas
asaabean
beanexception...(?)
exception...(?)
throw
thrownew
newEJBException(e);
EJBException(e); Call
Call is
is fielded
fielded
}}catch
catch(InvocationTargetException
(InvocationTargetExceptione) e){{ by
by the
the instance
instance
Throwable
Throwableex ex==e.getTargetException();
e.getTargetException();
…//end
…//end

© JBoss, Inc. 2003-2005. 49

Synchronization Interceptor Exit


Professional Open Source™

End of dive we are going back up!


We register a callback with JTA
– We will be notified of end of Tx
– Register with wrapper

After
After invoke()
invoke()
Or
Or in
in finally()
finally()
Synchronization
Transaction

Synchronization
Connection
Transaction

Connection
Security
Security

Cache
Cache
Lock
Lock
Log

Call
Log

Call

Invocation

© JBoss, Inc. 2003-2005. 50

25
Entity State-DB Synchronization
Professional Open Source™

org.jboss.ejb.plugins.EntitySynchronizationInterceptor
org.jboss.ejb.plugins.EntitySynchronizationInterceptor
private
privatevoid
voidregister(EntityEnterpriseContext
register(EntityEnterpriseContextctx,
ctx,Transaction
Transactiontx)
tx){{
////Create
Createaanew
newsynchronization
synchronization
InstanceSynchronization
InstanceSynchronizationsynch
synch==new
newInstanceSynchronization(tx,
InstanceSynchronization(tx,ctx);
ctx);

try
try{{ Implements
Implements
////We
Wewant
wanttotobebenotified
notifiedwhen
whenthe thetransaction
transactioncommits
commits javax.transaction.Synchronization
javax.transaction.Synchronization
tx.registerSynchronization(synch); interface
interface
tx.registerSynchronization(synch);
}}catch
catch(RollbackException
(RollbackExceptione)e){{
////The
Thestate
stateininthe
theinstance
instanceisistotobe
bediscarded,
discarded,we
weforce
forceaareload
reloadofofstate
state
ctx.setValid(false);
ctx.setValid(false);
}}catch
catch(Exception
(Exceptione)e){{
throw
thrownew
newEJBException(e);
EJBException(e);
}}
}}

© JBoss, Inc. 2003-2005. 51

Instance Interceptor Exit


Professional Open Source™

Acquisition interceptor
– Doesn’t do anything if Tx
– In case of stateless call frees the instance
– In case of Exception discards the instance
Synchronization
Transaction

Synchronization
Connection
Transaction

Connection
Security
Security

Cache
Cache
Lock
Lock
Log

Call
Log

Call

Invocation

© JBoss, Inc. 2003-2005. 52

26
Lock Interceptor Exit
Professional Open Source™

Lock Interceptor
– Cleans up any locks

Only
Only ifif part
part of
of the
the
same
same transaction
transaction

GO!
GO!

Synchronization
Transaction

Synchronization
Connection
Transaction

Connection
Security
Security

Cache
Cache
Lock
Lock
Log

Call
Log

Call
Invocation

© JBoss, Inc. 2003-2005. 53

Transaction Interceptor Exit


Professional Open Source™

Tx interceptor commits the transaction it started


The notification goes to the synchronization wrapper
THIS TRIGGERS THE PREVIOUS PERSISTENCE
Sync
Sync triggers
triggers
Tx
Tx commits
commits storage
storage
Notifies
Notifies Sync
Sync
Synchronization
Transaction

Synchronization
Connection
Transaction

Connection
Security
Security

Cache
Cache
Lock
Lock
Log

Call
Log

Call

Invocation

© JBoss, Inc. 2003-2005. 54

27
Entity State-DB Synchronization
Professional Open Source™

org.jboss.ejb.plugins.EntitySynchronizationInterceptor$InstanceSynchronization
org.jboss.ejb.plugins.EntitySynchronizationInterceptor$InstanceSynchronization
public
publicvoid voidafterCompletion(int
afterCompletion(intstatus)
status){{
....////skip
skip Transaction
Transaction
switch
switch(commitOption)
(commitOption) completed
completed
////Keep
Keepinstance
instancecached
cachedafter
aftertxtxcommit
commit
case
caseConfigurationMetaData.A_COMMIT_OPTION:
ConfigurationMetaData.A_COMMIT_OPTION:
////The
Thestate
stateisisstill
stillvalid
valid(only
(onlypoint
pointofofaccess
accessisisus)
us)
ctx.setValid(true);
ctx.setValid(true);
break;
break;

////Keep
Keepinstance
instanceactive,
active,but
butinvalidate
invalidatestate
state
case
caseConfigurationMetaData.B_COMMIT_OPTION:
ConfigurationMetaData.B_COMMIT_OPTION:
////Invalidate
Invalidatestate
state(there
(theremight
mightbebeother
otherpoints
pointsofofentry)
entry)
ctx.setValid(false);
ctx.setValid(false);
break;
break;

…////continue
continue

© JBoss, Inc. 2003-2005. 55

Entity State-DB Synchronization


Professional Open Source™

org.jboss.ejb.plugins.EntitySynchronizationInterceptor$InstanceSynchronization
org.jboss.ejb.plugins.EntitySynchronizationInterceptor$InstanceSynchronization
////Invalidate
Invalidateeverything
everythingAND ANDPassivate
Passivateinstance
instance
case
caseConfigurationMetaData.C_COMMIT_OPTION:
ConfigurationMetaData.C_COMMIT_OPTION:
try
try
{{
////Do
Donot
notcall
callrelease
releaseififgetId()
getId()isisnull.
null. This
Thismeans
meansthat
that
////the
theentity
entityhas
hasbeen
beenremoved
removedfrom fromcache.
cache.
////release
releasewill
willschedule
scheduleaapassivation
passivationand andthis
thisremoved
removedctx
ctx
////could
couldbe
beput
putback
backinto
intothe
thecache!
cache!
ifif(ctx.getId()
(ctx.getId()!=!=null)
null)container.getInstanceCache().release(ctx);
container.getInstanceCache().release(ctx);
}}

© JBoss, Inc. 2003-2005. 56

28
Conclusion
Professional Open Source™

EJB server side is implemented with


– Interceptors
– Plugins
– Services as MBean

You can specify interceptors at the EJB level


– Is externalized in standardjboss.xml or jboss.xml

You can specify interceptors at the XMBean level


– Is externalized in the XMBean descriptor

Interceptors implement any indirection and AOP you want


– Use locking to your advantage (be careful)
– Tweak caching to your advantage

© JBoss, Inc. 2003-2005. 57

29

Vous aimerez peut-être aussi