Title: Implementing Middleware with AOP
1Implementing Middleware with AOP
- JBoss Aspect Oriented Middleware
2Topics
- Overview
- From Interceptors to Aspects
- J2EE a la carte
- AOP metadata
- From Aspects to EJB3
- Proxy based AOP
- AOP Domains
- Annotations as Meta Model
- XML Annotations
- Dynamic AOP
- Transparent caching
- JBoss Cache Demo
- Designing a Cache
3AOP and Middleware
- Middleware is but a collection of cross-cutting
concerns - Most middleware already sort of aspectized
- CORBA and JBoss heavy use of interceptors
- Basing designs on AOP natural step
- Expensive to use regular OOP techniques to
mix/match configurations - Application is just configuration a set of
cross-cutting concerns - Natural step is to implement middleware using AOP
- More modular designs
- Less code clutter
4AOP and Middleware
- Aspect Oriented Middleware brings transparency
- System aspects can be made orthonogal
- Application code can free of system programming
- Middleware can be made simpler to use
5AOP Makes things Easier
- AOP to implement Ease-of-Use
- EJB 3 and annotation library implemented with AOP
- AOP for Ease-of-Extension
- Ease-of-use frameworks written on top of AOP
- AOP gives easy consistent way to extend behavior
6From Interceptors To Aspects
7JBoss 3.x Architecture
- J2EE behavior expressed as interceptors
- Detyped method invocations
Server JVM
- Internally invocation objects are routed within
the kernel
EJB Container MBean
RemoteInvoker
Port 1234
Client JVM
EJB Container MBean
Typed Interface
Invocation
JMX Microkernel
Client
RemoteInvoker
011101010101
Port 4321
Service MBean
Client Proxy
8Cross-cutting Concern
ltcontainer-configurationgt
ltcontainer-namegtStandard CMP 2.x
EntityBeanlt/container-namegt
ltcontainer-interceptorsgt
ltinterceptorgtorg.jboss.ejb.plugins.ProxyFactoryFin
derInterceptorlt/interceptorgt
ltinterceptorgtorg.jboss.ejb.plugins.LogInterceptorlt
/interceptorgt ltinterceptorgtorg.jboss.ejb.p
lugins.SecurityInterceptorlt/interceptorgt
ltinterceptorgtorg.jboss.ejb.plugins.TxInterceptorCM
Tlt/interceptorgt ltinterceptorgtorg.jboss.ejb
.plugins.CallValidationInterceptorlt/interceptorgt
ltinterceptorgtorg.jboss.ejb.plugins.EntityCr
eationInterceptorlt/interceptorgt
ltinterceptorgtorg.jboss.ejb.plugins.EntityLockInter
ceptorlt/interceptorgt ltinterceptorgtorg.jbos
s.ejb.plugins.EntityInstanceInterceptorlt/intercept
orgt ltinterceptorgtorg.jboss.ejb.plugins.Ent
ityReentranceInterceptorlt/interceptorgt
ltinterceptorgtorg.jboss.resource.connectionmanager.
CachedConnectionInterceptorlt/interceptorgt
ltinterceptorgtorg.jboss.ejb.plugins.EntitySynchroni
zationInterceptorlt/interceptorgt
ltinterceptorgtorg.jboss.ejb.plugins.cmp.jdbc.JDBCRe
lationInterceptorlt/interceptorgt
lt/container-interceptorsgt
9Cross-cutting Concern
ltcontainer-configurationgt
ltcontainer-namegtStandard CMP 2.x
EntityBeanlt/container-namegt
ltcontainer-interceptorsgt
ltinterceptorgtorg.jboss.ejb.plugins.ProxyFactoryFin
derInterceptorlt/interceptorgt
ltinterceptorgtorg.jboss.ejb.plugins.LogInterceptorlt
/interceptorgt ltinterceptorgtorg.jboss.ejb.p
lugins.SecurityInterceptorlt/interceptorgt
ltinterceptorgtorg.jboss.ejb.plugins.TxInterceptorCM
Tlt/interceptorgt ltinterceptorgtorg.jboss.ejb
.plugins.CallValidationInterceptorlt/interceptorgt
ltinterceptorgtorg.jboss.ejb.plugins.EntityCr
eationInterceptorlt/interceptorgt
ltinterceptorgtorg.jboss.ejb.plugins.EntityLockInter
ceptorlt/interceptorgt ltinterceptorgtorg.jbos
s.ejb.plugins.EntityInstanceInterceptorlt/intercept
orgt ltinterceptorgtorg.jboss.ejb.plugins.Ent
ityReentranceInterceptorlt/interceptorgt
ltinterceptorgtorg.jboss.resource.connectionmanager.
CachedConnectionInterceptorlt/interceptorgt
ltinterceptorgtorg.jboss.ejb.plugins.EntitySynchroni
zationInterceptorlt/interceptorgt
ltinterceptorgtorg.jboss.ejb.plugins.cmp.jdbc.JDBCRe
lationInterceptorlt/interceptorgt
lt/container-interceptorsgt
Extract Aspects
Extract Aspects
10Interceptors to Aspects
- Aspectizing JBoss seemed like logical next step
- Leverage pointcut expressions
- Bring J2EE a la cart to plain Java
- Leverage our existing interceptor design
11J2EE a la carte
12Transaction Demarcation
- Transaction demarcation (method, field,
constructor) - You can specify transaction boundaries within
code - Tags can transparently interact with Transaction
Manager - Begin, suspend, commit and rollback transactions
- On method, field, or constructor execution
- EJB adjectives used to specify transactional
behavior - Required, RequiresNew, Supports, Never,
NotSupported, Mandatory - Complete control over when a rollback is
triggered - i.e. which thrown exceptions cause a rollback
13Transaction Demarcation
- Annotations or XML metadata can specify
annotation
_at_Tx(TxType.REQUIRED) public void somepojoMethod()
ltmetadata tag"transaction" class"org.jboss.test.
POJO"gt ltmethod name"somepojoMethodgt ltvaluegtRequi
resNewlt/valuegt lt/methodgt lt/metadatagt
14Roled-based Security
- Secured access to any method, field, or
constructor - Only users of a certain role allowed to access
- Authentication/Authorization integrated with
JBoss Security - Various Security Domains (LDAP, RDBMS, SRP, etc)
- Access to username available within other
interceptors
15Role-Based security
- JDK 5.0 Annotations are usable
_at_SecurityDomain(other) public class POJO
_at_Unchecked public POJO() _at_Exclude public
exlucedMethod() _at_Permissions(admin,
manager) public void someMethod()
_at_Permissions(user) public static int
status
16Role-Based security
- XML metadata can specify annotation
ltmetadata tag"security" class"org.jboss.test.aop
.bean.SecuredPOJO"gt ltsecurity-domaingtotherlt/sec
urity-domaingt ltmethod-permissiongt
ltrole-namegtallowedlt/role-namegt
ltmethodgtltmethod-namegtsomeMethodlt/method-namegtlt/met
hodgt lt/method-permissiongt
ltconstructor-permissiongt ltunchecked/gt
ltconstructorgtltconstructor-params/gtlt/constructorgt
lt/constructor-permissiongt ltexclude-listgt
ltdescriptiongtMethods that connect be
usedlt/descriptiongt ltmethodgt
ltmethod-namegtexcludedlt/method-namegt
lt/methodgt lt/exclude-listgt lt/metadatagt
17Metadata
18Metadata
- J2EE a la carte examples show importance of
metadata - Pointcut expressions arent always the silver
bullet - Can be confusing to developers
- Developers want simple, familiar ways of applying
aspects - Some developers like annotations
- Others prefer XML to externalize configuration
- An AOP framework needs to be aware of both.
19Metadata
- JBoss AOP requirements
- Support annotations in pointcut expressions
- Support annotation overrides at runtime
- Support untyped metadata
- Support metadata/annotation defaults
- Support XML externalization of metadata
- Allow metadata/annotations to be attached without
modifying bytecode - Metadata changeable on a per-deployment basis
through XML - Allow pointcut expressions to be aware of this
attached metadata.
20Dynamic Metadata
- Aspects can resolve metadata dynamically
- The AOP Invocation object (ThisJoinPoint) gives
hooks for this. - Metadata can be attached to a invocation and
propagated - Aspects can pass information to one another
locally or remotely - Metadata can be overridden on a per Thread basis
- Change behavior per Thread
- Provide simple mechanism to clear all Thread
metadata (Thread Pooling) - Default values can be defined/managed per VM or
per Cluster
Invocation
Thread
Class
VM
Cluster
21EJB 3.0 and JBoss AOP
- An aspect-oriented EJB container
22EJB 3.0 and JBoss AOP
- Can EJB be implemented using AOP?
- Traditional AspectJ like weaving not possible
- EJB is a proxy architecture by definition
- proxy.someMethod() different behavior than
this.someMethod() - Same class can be deployed in multiple containers
- Mix/match of XML and Annotations
- JBoss 3.x and lower showed AOP was the right
approach - A Proxy-based AOP container was needed.
23EJB 3.0 and JBoss AOP
- JBoss AOP binds aspects at class load time
- Since binding is java.lang.reflection based
- Very easy to create a proxy container a.k.a an
EJB container
Server JVM
AOP Container
RemoteInvoker
Port 1234
Client JVM
Typed Interface
Invocation
JBoss Remoting
AOP Container
Client
RemoteInvoker
011101010101
Port 4321
Client Proxy
24EJB 3.0 and JBoss AOP
- Why re-architect within an AOP Container?
- Full pointcut expressions available
- Per method advice chains
- Pluggable annotations
- Pluggable behavior
- Reuse existing Aspect Library
- Remember?
- If middleware is easy to use
- it should also be easy to extend
- AOP allows us to easily extend EJB behavior
25EJB 3.0 and JBoss AOP
- The next issue
- EJB Containers have similar, but different
aspects - Stateless, Stateful, MDB (and JBoss extensions)
- Proxies to these container types also similar but
different - Needed a way to define a template for each of
these types - Needed a way to define a template for proxy
definition - Solution
- JBoss AOP Aspect Domains
26Aspect Domains
- Advice Stacks
- Named chain of unbound advices
- Proxies use these to understand what their
advices should be - Aspect Domains
- Define a set of pointcuts, metadata overrides,
and advice bindings - Containers reference domains for their advices
- Domains can inherit from one-another
27Advice stacks
- Containers reference advice stacks when they
create proxies - Stacks are predefined and configurable
ltstack name"SessionBeanClientInterceptors"gt
ltinterceptor-ref name"org.jboss.aspects.remotin
g.IsLocalInterceptor"/gt ltinterceptor-ref
name"org.jboss.aspects.security.SecurityClientInt
erceptor"/gt ltinterceptor-ref
name"org.jboss.aspects.tx.ClientTxPropagationInte
rceptor"/gt ltinterceptor-ref
name"org.jboss.aspects.remoting.InvokeRemoteInter
ceptor"/gt lt/stackgt
28Aspect Domains
ltdomain name"Stateless Bean"gt ltbind
pointcut"execution( _at_org.jboss.ejb3.security.Sec
urityDomain-gt(..))"gt ltinterceptor-ref
name"org.jboss.ejb3.security.AuthenticationInterc
eptorFactory"/gt ltinterceptor-ref
name"org.jboss.ejb3.security.RoleBasedAuthorizati
onInterceptorFactory"/gt lt/bindgt ltbind
pointcut"execution( _at_javax.ejb.RunAs-gt(..))"gt
ltinterceptor-ref name"org.jboss.ejb3.secu
rity.RunAsSecurityInterceptor"/gt lt/bindgt
ltbind pointcut"execution( -gt(..))"gt
ltinterceptor-ref name"org.jboss.ejb3.stateless.
StatelessInstanceInterceptor"/gt
ltinterceptor-ref name"org.jboss.aspects.tx.TxProp
agationInterceptor"/gt ltinterceptor-ref
name"org.jboss.ejb3.tx.TxInterceptorFactory"/gt
lt/bindgt ltannotation expr"!class(_at_org.jb
oss.ejb3.PoolClass)"gt _at_org.jboss.ejb3.Poo
lClass (valueorg.jboss.ejb3.ThreadlocalPool.class
, maxSize30, timeout10000) lt/annotationgt
lt/domaingt
Annotations with behavior
Default advices
Annotation Override
29Dynamic AOP
30What is Dynamic AOP ?
- Hot-deployment of aspects
- Bind/unbind advices arbitrarily at runtime
- Per-instance AOP
- Add advices on a per instance basis
31What is JBossCache ?
- Transparent caching
- Local or replicated
- Synchronous or asynchronous replication (using
JGroups) - Transactional or non-transactional
- Transactional
- Replication at TX commit
- DB isolation levels supported
- Support for pluggable TxManagers
- Non-Transactional
- Replication after each modification
- Pluggable eviction policies
- Ships with time-based and size-based (LRU)
policies - Cache loader
- Persistent backend store (load - store)
32AOP Cache
public class Person String namenull int
age0 Map hobbiesnull Address
addressnull Set skills List languages
public String getName() return name
public void setName(String name)
this.namename ...
public class Address String streetnull
String citynull int zip0 public String
getStreet() return street
public void setStreet(String street)
this.streetstreet ...
33Interaction With Cache
tree new TreeCacheAop()config new
PropertyConfigurator()// configure tree
cache.config.configure(tree, "META-INF/replSync-s
ervice.xml")joe new Person()joe.setName("Jo
e Black")joe.setAge(31)addr new
Address()addr.setCity("Sunnyvale")addr.setStre
et("123 Albert Ave")addr.setZip(94086)joe.set
Address(addr)
Use Pojos as Pojos
34Interaction With Cache
- Joes state is automatically transactional and
replicated - State replicated, synchronized at transaction
commit/rollback
tree.start()Â // kick start tree
cachetree.putObject("/aop/joe", joe) // add aop
sanctioned object tx.begin()joe.setAge(41)jo
e.getAddress().setZip(95124)tx.commit()
35Demo JBossCache
36How does it work?
- Classes must be prepared for field interception
- This preparation creates AOP hooks
- Any advice can be added where hooks are
instrumented
lt?xml version"1.0" encoding"UTF-8"?gt ltaopgt
ltprepare expr"field( instanceoforg.jboss.test.
cache.test.standAloneAop.Student-gt)" /gt
ltprepare expr"field( instanceoforg.jboss.test.
cache.test.standAloneAop.Address-gt)" /gt
ltprepare expr"field( instanceoforg.jboss.test.
cache.test.standAloneAop.Person-gt)" /gt lt/aopgt
37How does it work?
- Uses reflection to discover the structure of a
POJO - Requires a jboss-aop.xml to declare user-defined
class to be advisable - Uses AOP to keep track of changes to a POJO
- putObject() breaks an object apart and maps it
to the TreeCache - Primitive fields are mapped to entries in a
node's attributes - Complex fields are mapped to child nodes
(recursively) - Transparent handling of object hierarchies
- No need for one-to-one, one-to-many, etc
relationship declarations - POJO inheritance hierarchy is preserved
- We dynamically add a field advice to each complex
object to keep track of state changes
38JBoss Cache - Advices
- Each advice remembers the node to which it maps
- On field read advice returns the value from the
TreeCache - On field write advice updates the associated
node's attributes, e.g. - person.getAddress().setCity("San Jose) generates
a put("/322649/addr", "city", "San Jose") - On TX commit modified fields are replicated and
written back to the POJO
39JBoss Cache - Design
- Cache design itself can aspectized
- Cache Aspects
- CacheLoader, cache persistence
- Replication
- Transactionality
- Cannot aspectize using class-level weaving
- Same classes but configured differently per
instance - Aspects can only be assembled if AOP framework
support Dynamic AOP
40JBoss Strategy
- Middleware is the perfect application of AOP
- Transparency
- Flexibility
- Annotations for ease of use
- AOP for ease of extension