professional open source © jboss group, 2003. 1 12 september 2015 jboss: aspect-oriented middleware...
TRANSCRIPT
Professional Open Source
© JBoss Group, 2003. 1April 21, 2023
JBoss: Aspect-Oriented Middleware
Aspect Oriented Programming with JBoss 4
AOSD, 2004
Bill Burke
Chief Architect, JBoss Inc.
© JBoss Group, 2003. 2
Professional Open Source
Overall Agenda
What is AOP?
JBoss AOP framework
Prepackaged Middleware Aspects– Dynamic Aspects
– Metadata Driven Aspects
© JBoss Group, 2003. 3
Professional Open Source
What is it?
Orthogonal to class hierarchies Cross-cutting functionality Functionality spanning across class hierarchies Aspects are generic services that can be applied across domains Functionality that is not specific to any particular class
Class1
Class2 Class3 Class4
Class1
Class2 Class3 Class4
CROSS HIERARCHY
© JBoss Group, 2003. 4
Professional Open Source
What is it NOT?
AOP != OOP AOP is not better than OOP AOP compliments OOP
AOPites say OOP solves 80% of problems well AOP solves the 20% OOP isn’t good at
© JBoss Group, 2003. 5
Professional Open Source
Cross-cutting Concern
public class BankAccount {
public void withdraw(double amount) {
long start = System.currentTimeMillis();
try {
Connection con = datasource.getConnection();
con.execute…(“select … blah blah”);
this.balance -= amount;
con.commit();
}
finally {
long totalTime = System.currentTimeMillis() - start;
System.out.println(“withdraw took “ + start);
}
}
}
public class BankAccount {
public void withdraw(double amount) {
long start = System.currentTimeMillis();
try {
Connection con = datasource.getConnection();
con.execute…(“select … blah blah”);
this.balance -= amount;
con.commit();
}
finally {
long totalTime = System.currentTimeMillis() - start;
System.out.println(“withdraw took “ + start);
}
}
}
© JBoss Group, 2003. 6
Professional Open Source
Cross-cutting Concern
public class BankAccount {
public void withdraw(double amount) {
long start = System.currentTimeMillis();
try {
Connection con = datasource.getConnection();
con.execute…(“select … blah blah”);
this.balance -= amount;
con.commit();
}
finally {
long totalTime = System.currentTimeMillis() - start;
System.out.println(“withdraw took “ + totalTime);
}
}
}
public class BankAccount {
public void withdraw(double amount) {
long start = System.currentTimeMillis();
try {
Connection con = datasource.getConnection();
con.execute…(“select … blah blah”);
this.balance -= amount;
con.commit();
}
finally {
long totalTime = System.currentTimeMillis() - start;
System.out.println(“withdraw took “ + totalTime);
}
}
}
© JBoss Group, 2003. 7
Professional Open Source
What’s wrong?
Difficult to turn metrics off/on– Have to modify every method you want it in
Bloated code, harder to read Metrics doesn’t belong To expand metrics functionality, need to modify lots of code.
© JBoss Group, 2003. 8
Professional Open Source
Where does AOP come in?
Can encapsulate metrics functionality in one place Remove metrics from polluting your code Expression language for defining where you want an aspect to go
© JBoss Group, 2003. 9
Professional Open Source
Terms
Advice– Behavior you want to weave into your Java classes (metrics code)
Aspect– Java class that encapsulates advices
Pointcut– Expression specifying a point within Java code
– i.e. a method call, field access, construction
Joinpoint– Actual point a pointcut matches on
– A method execution
– A field access
Invocation– JBoss AOP’s runtime encapsulation of a pointcut
© JBoss Group, 2003. 10
Professional Open Source
Aspects
Advice is the behavior you want to add Aspects encapsulate this behavior
public class MetricsAspect {
public Object profile(Invocation invocation) throws Throwable {
long start = System.currentTimeMillis();
try {
return invoke.invokeNext();
} finally {
long totalTime = System.currentTimeMillis() - start; System.out.println(“invocation took “ + totalTime); } }}
public class MetricsAspect {
public Object profile(Invocation invocation) throws Throwable {
long start = System.currentTimeMillis();
try {
return invoke.invokeNext();
} finally {
long totalTime = System.currentTimeMillis() - start; System.out.println(“invocation took “ + totalTime); } }}
Advice
© JBoss Group, 2003. 11
Professional Open Source
Pointcuts and Bindings
Apply the Metrics aspect to our BankAccount class Pointcut expression defines where we want metrics to be invoked
<aop>
<aspect class=“org.jboss.MetricsAspect”/>
<bind pointcut=“execution(public * BankAccount->*(..))”>
<advice aspect=“org.jboss.MetricsAspect” name=“profile”/>
</bind>
</aop>
<aop>
<aspect class=“org.jboss.MetricsAspect”/>
<bind pointcut=“execution(public * BankAccount->*(..))”>
<advice aspect=“org.jboss.MetricsAspect” name=“profile”/>
</bind>
</aop>
© JBoss Group, 2003. 12
Professional Open Source
JBoss AOP Framework
Basic Features:– Execution pointcut definition for fields, constructors and methods
– Caller pointcut definition for constructors and methods
– Compositional pointcuts through an expression language
– Control Flow pointcuts
– Interface introductions and mixins – Multiple inheritance with mixins
– Load or compile time bytecode enhancements
– Doclet integration through QDox
– 100% pure Java
– Available integrated with application server
– Can run standalone in any Java program as well
© JBoss Group, 2003. 13
Professional Open Source
JBoss AOP Framework
Distinguishing Features:– Dynamic API
• Advice bindings on a per instance basis
• Metadata bindings on a per instance basis
– Hot Deployment of advice bindings at runtime
– Metadata facility for JDK 1.4 (JSR-175 like annotations)
– Annotation support in pointcut language
– Configuration Domains
– Runtime GUI management console
Professional Open Source
© JBoss Group, 2003. 14April 21, 2023
Prepackaged Middleware AspectsApplied AOP
© JBoss Group, 2003. 15
Professional Open Source
JBoss 4: Pre-packaged Aspects
Middleware, by nature, is cross-cutting Middleware implemented as aspects allows for:
– Smooth, fluid, iterative development
– Clean separation between System Architect and Application Developer
– Less upfront design decisions
AOP is the natural evolution of middleware JBoss 4 is Aspect-Oriented Middleware
© JBoss Group, 2003. 16
Professional Open Source
Iterative Development
Specifications like EJB requires upfront design decisions AOP provides clean separation from system architecture and application
code Architectural decisions can be made later on in the development process AOP makes iterative development more fluid
© JBoss Group, 2003. 17
Professional Open Source
JBoss 4: Pre-packaged Aspects
Annotated aspects:– J2EE a la carte
• Transaction demarcation
• Role-based Security
– Transactional Locking. Expanded Java “synchronized”
Dynamic AOP– Transactional Objects. Our Transactional Cache
– Replicated Objects. Our Distributed Cache
– Remoting – choose at runtime, SOAP, RMI, Sockets, IIOP
– Clustered Remoting – invocation failover
Professional Open Source
© JBoss Group, 2003. 18April 21, 2023
Annotated Aspects
© JBoss Group, 2003. 19
Professional Open Source
Annotations and AOP
Annotations + AOP allows you to extend the Java language
Instead of code generation– Encapsulate middleware as aspects
– Apply the middleware through annotations
– Let middleware become part of the Java language
Let’s give an example using JBoss AOP– Define a ReadWriteLock
© JBoss Group, 2003. 20
Professional Open Source
Define Annotation
Define the syntax to our “extension” of the Java language
public @interface ReadLocked {}
public @interface WriteLocked {}
public @interface ReadLocked {}
public @interface WriteLocked {}
© JBoss Group, 2003. 21
Professional Open Source
ReadWriteLock Aspect
public class ReadWriteLockAspect {
java.util.concurrent.ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
public Object readLock(Invocation invocation) throws Throwable {
lock.readLock().lock();
try {
return invoke.invokeNext();
} finally {
lock.readLock().unlock(); } }
public Object writeLock(Invocation invocation) throws Throwable { lock.writeLock().lock(); try { return invoke.invokeNext(); } finally {
lock.writeLock().unlock(); } }}
public class ReadWriteLockAspect {
java.util.concurrent.ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
public Object readLock(Invocation invocation) throws Throwable {
lock.readLock().lock();
try {
return invoke.invokeNext();
} finally {
lock.readLock().unlock(); } }
public Object writeLock(Invocation invocation) throws Throwable { lock.writeLock().lock(); try { return invoke.invokeNext(); } finally {
lock.writeLock().unlock(); } }}
Advice
Advice
© JBoss Group, 2003. 22
Professional Open Source
Pointcuts and Bindings
Specify pointcuts that triggers the application of the ReadWriteLockAspect @ReadLocked triggers readLock advice @WriteLocked triggers writeLock advice
<aop>
<aspect class=“ReadWriteLockAspect” scope=“PER_INSTANCE”/>
<bind pointcut=“execution(public !static * *>@org.jboss.ReadLocked(..))”>
<advice aspect=“ReadWriteLockAspect” name=“readLock”/>
</bind>
<bind pointcut=“execution(public !static * *>@org.jboss.WriteLocked(..))”> <advice aspect=“ReadWriteLockAspect” name=“writeLock”/> </bind>
</aop>
<aop>
<aspect class=“ReadWriteLockAspect” scope=“PER_INSTANCE”/>
<bind pointcut=“execution(public !static * *>@org.jboss.ReadLocked(..))”>
<advice aspect=“ReadWriteLockAspect” name=“readLock”/>
</bind>
<bind pointcut=“execution(public !static * *>@org.jboss.WriteLocked(..))”> <advice aspect=“ReadWriteLockAspect” name=“writeLock”/> </bind>
</aop>
© JBoss Group, 2003. 23
Professional Open Source
Use our Language “Extension”
Use our new addition to the Java language: @ReadLocked, @WriteLocked
public class BankAccount
{
@ReadLocked Data pullAccountData() {…}
@WriteLocked void updateAccountData() {…}
}
public class BankAccount
{
@ReadLocked Data pullAccountData() {…}
@WriteLocked void updateAccountData() {…}
}
Professional Open Source
© JBoss Group, 2003. 24April 21, 2023
JBoss Packaged Annotated Aspects
© JBoss Group, 2003. 25
Professional Open Source
Asynchronous Invocations
Asynchronous Aspect– Tag Methods
– Invoke them in background
– Obtain response asynchronously
– In-VM only
– Working on Remote asynchronous invocations
© JBoss Group, 2003. 26
Professional Open Source
Asynchronous Invocations
@asynchronous
public int somepojoMethod() { … }
{
POJO pojo = new POJO();
AsynchronousFacade façade = (AsynchronousFacade)pojo;
pojo.somepojoMethod(); // happens in background
AsynchronousResponse response = facade.waitForResponse();
int rtn = ((Integer)response.getResponse()).intValue();
}
@asynchronous
public int somepojoMethod() { … }
{
POJO pojo = new POJO();
AsynchronousFacade façade = (AsynchronousFacade)pojo;
pojo.somepojoMethod(); // happens in background
AsynchronousResponse response = facade.waitForResponse();
int rtn = ((Integer)response.getResponse()).intValue();
}
Professional Open Source
© JBoss Group, 2003. 27April 21, 2023
J2EE a la carte
© JBoss Group, 2003. 28
Professional Open Source
Transaction 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
© JBoss Group, 2003. 29
Professional Open Source
Transaction Demarcation
Annotations or XML metadata can specify annotation
@Tx(TxType.REQUIRED)
public void somepojoMethod() { … }
@Tx(TxType.REQUIRED)
public void somepojoMethod() { … }
<annotation tag="transaction" class="org.jboss.test.POJO">
<method name="somepojoMethod“>
<value>RequiresNew</value>
</method></annotation>
<annotation tag="transaction" class="org.jboss.test.POJO">
<method name="somepojoMethod“>
<value>RequiresNew</value>
</method></annotation>
© JBoss Group, 2003. 30
Professional Open Source
Transactional Locking
Enhanced Java “synchronized” Allows you to lock object/class for duration of a transaction Can specify on any member field or method
– Locks object instance
Can specify for any constructor or static method, field– Locks class access
© JBoss Group, 2003. 31
Professional Open Source
Transactional Locking
Annotations or XML metadata can specify annotation
@TxSynchronized
public void somepojoMethod() { … }
<annotation tag="transactionSynchronized" class="org.jboss.test.POJO"> <method name="somepojoMethod“/></annotation>
@TxSynchronized
public void somepojoMethod() { … }
<annotation tag="transactionSynchronized" class="org.jboss.test.POJO"> <method name="somepojoMethod“/></annotation>
© JBoss Group, 2003. 32
Professional Open Source
Roled-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
© JBoss Group, 2003. 33
Professional Open Source
Role-Based security
XML metadata can specify annotation
<annotation tag="security" class="org.jboss.test.aop.bean.SecuredPOJO"> <security-domain>other</security-domain> <method-permission> <role-name>allowed</role-name> <method><method-name>someMethod</method-name></method> </method-permission> <constructor-permission> <unchecked/> <constructor><constructor-params/></constructor> </constructor-permission> <exclude-list> <description>Methods that connect be used</description> <method> <method-name>excluded</method-name> </method> </exclude-list></annotation>
<annotation tag="security" class="org.jboss.test.aop.bean.SecuredPOJO"> <security-domain>other</security-domain> <method-permission> <role-name>allowed</role-name> <method><method-name>someMethod</method-name></method> </method-permission> <constructor-permission> <unchecked/> <constructor><constructor-params/></constructor> </constructor-permission> <exclude-list> <description>Methods that connect be used</description> <method> <method-name>excluded</method-name> </method> </exclude-list></annotation>
© JBoss Group, 2003. 34
Professional Open Source
Role-Based security
JDK 5.0 Annotations are usable
@SecurityDomain(“other”)
public class POJO {
@Unchecked public POJO() {}
@Exclude public exlucedMethod() {…}
@Permissions({“admin”, “manager”})
public void someMethod() {…}
@Permissions({“user”})
public static int status;
}
@SecurityDomain(“other”)
public class POJO {
@Unchecked public POJO() {}
@Exclude public exlucedMethod() {…}
@Permissions({“admin”, “manager”})
public void someMethod() {…}
@Permissions({“user”})
public static int status;
}
© JBoss Group, 2003. 35
Professional Open Source
Role-based Security
Security information is available within advice/interceptors– Useful if you want to do your own rule-based security
import java.security.Principal;
public Object invoke(org.jboss.aop.joinpoint.Invocation invocation) throws Throwable{ Principal principal = (Principal)invocation.getMetaData("security", "principal");…}
import java.security.Principal;
public Object invoke(org.jboss.aop.joinpoint.Invocation invocation) throws Throwable{ Principal principal = (Principal)invocation.getMetaData("security", "principal");…}
Professional Open Source
© JBoss Group, 2003. 36April 21, 2023
Dynamic AOP
© JBoss Group, 2003. 37
Professional Open Source
Dynamic AOP
Every AOPized class has an extended interface At classloading time, bytecode manipulation forces AOP POJOs to
implement a standard AOP interface.
package org.jboss.aop;
Public interface Advised
{
Advisor _getAdvisor();
InstanceAdvisor _getInstanceAdvisor();
}
package org.jboss.aop;
Public interface Advised
{
Advisor _getAdvisor();
InstanceAdvisor _getInstanceAdvisor();
}
© JBoss Group, 2003. 38
Professional Open Source
Dynamic AOP
Dynamic insertion of interceptors per object instance Object instance can hold its own metadata
package org.jboss.aop;public interface InstanceAdvisor{ public SimpleMetaData getMetaData(); public Interceptor[] getInterceptors(); public Interceptor[] getInterceptors(Interceptor[] baseChain); public boolean hasAspects();
public void insertInterceptor(Interceptor interceptor); public void removeInterceptor(String name); public void appendInterceptor(Interceptor interceptor);
public void insertInterceptorStack(String stackName); public void removeInterceptorStack(String name); public void appendInterceptorStack(String stackName);}
package org.jboss.aop;public interface InstanceAdvisor{ public SimpleMetaData getMetaData(); public Interceptor[] getInterceptors(); public Interceptor[] getInterceptors(Interceptor[] baseChain); public boolean hasAspects();
public void insertInterceptor(Interceptor interceptor); public void removeInterceptor(String name); public void appendInterceptor(Interceptor interceptor);
public void insertInterceptorStack(String stackName); public void removeInterceptorStack(String name); public void appendInterceptorStack(String stackName);}
Professional Open Source
© JBoss Group, 2003. 39April 21, 2023
JBoss Remoting
© JBoss Group, 2003. 40
Professional Open Source
JBossRemoting
Goals– Use POJOs not APIs
– No extending of UnicastRemote
– No precompilation (rmic)
– Protocol independent
– Protocol isolation
Features– SOAP, Fact Socket, or RMI protocols available
– Clustering: failover, loadbalancing
– URL based protocols (SOAP, RMI, FastSocket, etc…)
– Remote classloading with any protocol
© JBoss Group, 2003. 41
Professional Open Source
Remoting
Declare POJO remoted at runtime URI based protocols (soap, socket, rmi)
// Server
POJO remote = new POJO("hello");
Dispatcher.singleton.registerTarget(“objName", remote);
// Client
POJO proxy = (POJO)Remoting.createRemoteProxy(“objName",
POJO.class,
“soap://localhost:8080");
// Server
POJO remote = new POJO("hello");
Dispatcher.singleton.registerTarget(“objName", remote);
// Client
POJO proxy = (POJO)Remoting.createRemoteProxy(“objName",
POJO.class,
“soap://localhost:8080");
© JBoss Group, 2003. 42
Professional Open Source
JBossRemoting
Proxies can be created from a plain Java class.– AOP Framework has a proxy generation utility
– Same as java.lang.reflect.Proxy except it works with classes instead of interfaces
Remoting framework can also create proxies using plain old java.lang.reflect.Proxy if you like
Interceptors that handle transaction and security propagation are attached
Can run outside of JBoss application server
© JBoss Group, 2003. 43
Professional Open Source
Clustered Remoting
Invocation failover with any protocol Invocation loadbalancing with any protocol Leverages existing JBoss Clustering Requires JBoss application server
POJO pojo = new POJO("hello");
POJO proxy = (POJO)ClusteredRemoting.registerClusteredObject(
“objName",
pojo,
"DefaultPartition",
new RoundRobin(),
“socket://localhost:5150");
POJO pojo = new POJO("hello");
POJO proxy = (POJO)ClusteredRemoting.registerClusteredObject(
“objName",
pojo,
"DefaultPartition",
new RoundRobin(),
“socket://localhost:5150");
Professional Open Source
© JBoss Group, 2003. 44April 21, 2023
JBossCacheApplication of Dynamic AOP
© JBoss Group, 2003. 45
Professional Open Source
Features
AOP and non-AOP– AOP version uses Dynamic API for per instance field interception– Non-AOP can run with plain non-AOPized POJOs
Transactions– All modifications done within TX, replication at TX commit. No replication on
rollback Locking
– Access to nodes serialized by locks– Lock acquisition timeouts used for deadlock prevention
Replication– local: in-VM, no replication– repl-async: replication done on separate thread– repl-sync: replication done on user's thread, wait for all acks
All combinations supported– From local/no-tx/no-locking to repl/tx/locking– Ex: repl-async/no-locking/TX
© JBoss Group, 2003. 46
Professional Open Source
AOP Cache
AOP Cache POJO inserted into cache
– Can become Transactional
– Can become Replicated
– Depends on Cache Configuration
Goal to have transparent transactional properties Transparent Replication No application coding for inserted Objects Uses AOP Dynamic API and field interception Requires “prepare” step via <prepare>
© JBoss Group, 2003. 47
Professional Open Source
AOP Cache
Work with POJOs
public class Person { String name=null; int age=0; Map hobbies=null; Address address=null; Set skills; List languages;
public String getName() { return name; }
public void setName(String name) { this.name=name; } ...}
public class Person { String name=null; int age=0; Map hobbies=null; Address address=null; Set skills; List languages;
public String getName() { return name; }
public void setName(String name) { this.name=name; } ...}
public class Address { String street=null; String city=null; int zip=0;
public String getStreet() { return street; }
public void setStreet(String street) { this.street=street; } ...}
public class Address { String street=null; String city=null; int zip=0;
public String getStreet() { return street; }
public void setStreet(String street) { this.street=street; } ...}
© JBoss Group, 2003. 48
Professional Open Source
Interaction With Cache
tree = new TreeCacheAop();
config = new PropertyConfigurator();// configure tree cache.config.configure(tree, "META-INF/replSync-service.xml");
joe = new Person();joe.setName("Joe Black");joe.setAge(31);
addr = new Address();addr.setCity("Sunnyvale");addr.setStreet("123 Albert Ave");addr.setZip(94086);
joe.setAddress(addr);
tree = new TreeCacheAop();
config = new PropertyConfigurator();// configure tree cache.config.configure(tree, "META-INF/replSync-service.xml");
joe = new Person();joe.setName("Joe Black");joe.setAge(31);
addr = new Address();addr.setCity("Sunnyvale");addr.setStreet("123 Albert Ave");addr.setZip(94086);
joe.setAddress(addr);
Use Pojos as Pojos
© JBoss Group, 2003. 49
Professional Open Source
Interaction With Cache
Joe’s 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);joe.getAddress().setZip(95124);tx.commit();
tree.start(); // kick start tree cachetree.putObject("/aop/joe", joe); // add aop sanctioned object
tx.begin();joe.setAge(41);joe.getAddress().setZip(95124);tx.commit();
© JBoss Group, 2003. 50
Professional Open Source
Interaction with Cache
Any aop “prepared” class retains its reference Reference to addr is same as reference with joe
tx.begin();addr.setCity(“Santa Clara”);tx.commit();
joe.getAddress.getCity().equals(“Santa Clara”);
joe.getAddress() == addr;
tx.begin();addr.setCity(“Santa Clara”);tx.commit();
joe.getAddress.getCity().equals(“Santa Clara”);
joe.getAddress() == addr;
© JBoss Group, 2003. 51
Professional Open Source
Interaction with Cache
System classes do not retain references and cannot be intercepted Collection classes are the exception (Set, Map, List) A proxy is created for these And state is copied around
Person monica = new Person(…);Map hobbies = monica.getHobbies();
tree.putObject("/aop/monica", monica); // add aop sanctioned object
monica.getHobbies() != hobbies;monica.getHobbies().size() == 0;
Tx.begin();monica.getHobbies().put(“cooking”, “always”);Tx.rollback();
Monica.getHobbies().size() == 0; // state change rolledback
Person monica = new Person(…);Map hobbies = monica.getHobbies();
tree.putObject("/aop/monica", monica); // add aop sanctioned object
monica.getHobbies() != hobbies;monica.getHobbies().size() == 0;
Tx.begin();monica.getHobbies().put(“cooking”, “always”);Tx.rollback();
Monica.getHobbies().size() == 0; // state change rolledback
© JBoss Group, 2003. 52
Professional Open Source
JBoss AOP Conclusions
AOP Framework– Hot deployment– Dynamic API– Metadata Integration– Seemless integration with JBoss architecture
Aspect-Oriented Middleware– Pojo based development– Free developers from specifications– Give vendors
© JBoss Group, 2003. 53
Professional Open Source
JBoss AOP INFO
Link– http://www.jboss.org/products/aop
Discussion on JBoss.org forum or jboss-dev mailing list Contact
– Bill Burke [email protected]