JBoss and Aspects for Middlware Components

Download Report

Transcript JBoss and Aspects for Middlware Components

JBoss and Aspects for
Middleware Components
Presented by: Alon Kama
Seminar on Aspect-Oriented Software
Development
Instructor: Prof. Shmuel Katz
Winter 2004-2005
Prologue
“AOP is an exciting new paradigm that should have
the same effect on SW dev that OOP had 15-20
years ago”
-- Bill Burke, chief architect, JBoss
• The goal of JBoss: deliver an enterprise-strength
application server that enables powerful usage of
aspects.
Introduction: Middleware
Middleware is composed of software that act as
intermediaries between different application components,
to ease programming, integration, and management.
caching
Application
Application
Middleware
Middleware
fault
tolerance
replication
security
logging
transactions
Network
Middleware: another view
• Middleware can also
be viewed in the
component model
Network
 Encapsulated software
that performs a service
 Accessed either locally
or remotely
Application
Director
y
Services
Security
Introduction: About JBoss™
•
Inc. is a for-profit company, developing
the JBoss Enterprise Middleware System
(JEMS)
 Free, open-source product; paid support, consulting,
and training
•
.ORG is a developer community site
 JBoss Inc. capitalizes on the open-source
community for contributing code, beta testing,
answering user questions
Introduction: About JEMS
• A suite of integrating, open-source components
for product development and execution
 JBoss Application Server J2EE compliant
 JBoss AOP Aspect oriented framework
• Tightly coupled with Application Server




JBoss jBPM workflow engine
JBoss Cache fine-grained caching engine
JGroups multicast communication module
JBoss IDE Eclipse-based dev environment
Introduction: JBoss AOP
• Yet another aspect-oriented framework?!?
• Yes, but:
 Not standalone, tightly integrated with other
software
 Easy management
 Ability to dynamically apply or disengage
aspects at runtime
 Professional support, consulting, and training
Agenda
• Review the JBoss method of defining and
specifying:
 Interceptors
 Pointcuts
 Advice
• Contrast with AspectJ
• Show applicability for middleware
JBoss and Java
• JBoss AOP is designed to be run using
JBoss Application Server
 J2EE 5.0 compliant
 100% Pure Java
• AOP constructs defined as pure Java classes
• Constructs bound using XML or Java annotations
Joinpoints
• JBoss defines invocation objects that
correlate to exposed joinpoints
 Method / Constructor invocation
 Field access
• AspectJ exposes a bit more
 Execution of catch block
 Static initialization
• Various syntactical differences (unimportant)
Defining the Pointcut:
interceptors
• Interceptors come between a method call and its
•
execution
Defining an interceptor in an XML file:
<bind pointcut="public void com.mc.BankAccountDAO->
withdraw(double
amount)">
<interceptor class="com.mc.Metrics"/>
</bind >
<bind pointcut="* com.mc.billing.*->*(..)">
<interceptor class="com.mc.Metrics"/>
</bind >
JBoss AOP Interceptor
public class Metrics implements org.jboss.aop.Interceptor {
public Object invoke(Invocation invocation) throws
Throwable{
long startTime = System.currentTimeMillis();
try {
return invocation.invokeNext();
}
finally {
long endTime = System.currentTimeMillis() - startTime;
java.lang.reflect.Method m =
((MethodInvocation)invocation).method;
System.out.println("method " + m.toString() + " time:
” + endTime + "ms");
}
}
}
J2SE5.0: Annotations
• An annotation is metadata that is written by
the programmer in the source file. Later, a
tool will process this and emit code
instead.
 Offers a “declarative” programming style
 Does not affect program semantics, but affects
the way a program is treated by tools and
libraries
Annotations: Example
• Defining an annotation type:
/** * Associates a copyright notice with the annotated API
* element.
*/
public @interface Copyright {
String authors();
String date() default “2005”;
}
• Annotation declaration:
@Copyright(
authors = “Alon”,
date = “16/1/05”
)
public class Foo {…}
 Means that Foo implements the Copyright interface,
using the initialization above the declaration
Annotations and AOP
• Example: add syntax to fire void methods
asynchronously:
import org.jboss.aspects.Oneway;
public class Foo {
@Oneway public static void someMethod() {...}
public static void main(String[] args) {
someMethod(); // executes in background
}
}
• Thus, easy to add an aspect element by way of
an interface (in this case, a method interface)
Defining syntax for @Oneway
• Defining the interface strictly for methods:
package org.jboss.aspects;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target({ElementType.METHOD})
public @interface Oneway {}
Defining aspect for @Oneway
• Defining the aspect
class:
public OnewayAspect {
private static class Task
implements
Runnable {
private
MethodInvocation invoc;
public
Task(MethodInvocation
invocation) {this.invoc
= invoc;}
public void run() {
try {
invoc.invokeNext(); }
catch (Throwable
ignore) { }
public Object oneway(MethodInvocation
invoc) throws Throwable {
MethodInvocation copy = invoc.copy();
Thread t =new Thread(new Task(copy));
t.setDaemon(false);
t.start();
return null;
}
}
Pointcut expression: @Oneway
<aop>
<aspect
class="org.jboss.aspects.OnewayAspect"/>
<bind pointcut=
"execution(void *>@org.jboss.Oneway(..))">
<advice name="oneway"
aspect="org.jboss.aspects.OnewayAspect"/>
</bind>
</aop>
Dependency Injection
• AOP can be used to specify dependencies
upon object declaration, and have those
dependencies met upon runtime
 Advantages: removal of dependency on
concrete classes and external configurability
 e.g. Vendor-specific access methods
• Can write a generic application and have user plug
in the appropriate database-specific classes (e.g.
Oracle, DB2)
Dependency Injection
• Example: A non-standardized way to access an
object location service
 Would like to inject an instance of this service for
every field that references it
• Define the annotation:
@Target({ElementType.FIELD})
public @interface Inject {}
 This defines the annotation for use on class’s fields
Dependency Injection
• Using the declaration in user’s code:
import org.jboss.aspects.Inject;
public class Foo {
@Inject private LocationService loc;
public void bar(String s) {
Object o = loc.lookup(s);
...
}
}
Dependency Injection
• Defining the aspect class:
public InjectLocAspect {
private LocationService loc = Magic.getInstance();
public Object access(FieldReadInvocation invocation)
throws Throwable { return loc;
}
public Object access(FieldWriteInvocation invocation)
throws Throwable {
throw new RuntimeException("Setting an @Injected
variable is illegal");
}
}
Dependency Injection
• Defining the XML binding:
<aop>
<aspect class=“org.jboss.aspects.InjectLocAspect”/>
<bind pointcut=
“field(LocationService*>@org.jboss.aspects.Inject)”>
<advice
name=“access”aspect=“org.jboss.aspects.InjectLocAsp
ect”/>
</bind>
</aop>
Dynamic AOP
• Advices and Interceptors can be added or
removed from any joinpoint at runtime.
 Useful for deploying and un-deploying metrics
or statistic gathering on an as-needed basis.
 For testing, allows to deploy/un-deploy testing
aspects while running automated tests
Adding Advice Binding
• At runtime, can add advice binding as
follows:
org.jboss.aop.advice.AdviceBinding binding =
new
AdviceBinding(“execution(POJO>new(..))”,null);
binding.addInterceptor(SimpleInterceptor.class);
AspectManager.instance().addBinding(binding);
Per-instance AOP
• Example: JBoss Cache AOP
(TreeCacheAOP).
 The cache performs automatic replication
across a cluster
• For maintaining consistency, necessitates that an
object’s field accesses are intercepted
Before:
Obj
While in
cache:
Obj
After
leaving
cache:
Obj
Per-instance AOP
• TreeCacheAOP uses AOP to prepare classes so
that field access may be intercepted.
 Upon inserting: adds field interceptors so that it can do
automatic replication
 Upon removing: the field interceptors are removed
• Does not affect object access when object is not
associated with the cache
Integration with pointcuts
• After productizing and shipping an application,
sometimes users want to integrate with it
 Users want “hooks” in different places of the
application so that they can trigger things specific to
their particular deployment
 If hooks are provided using OOP, it becomes tough to
redesign or change API.
 By using pointcuts, the application designer provides
logical names to pointcut expressions. The pointcut
expression can change over time but the logical name
stays the same
Testing an application
• Writing test suites to check all exception
handling is time-consuming and errorprone
 Need to write code to produce all error
conditions
 Using aspects, can test a live system by
deploying/un-deploying certain aspects at
runtime
Testing example
• Simulate SQL deadlock exception
public class SQLDeadlockExceptionInjector {
public Object throwDeadlock(Invocation invocation) throws
Throwable {
throw new SQLException("Oracle Deadlock",
"RETRY“,ORACLE_DEADLOCK_CODE);
}
}
• Advice to intercept execute() methods of
java.sql.Statement
<aspect class="SQLDeadlockExceptionInjector/>
<bind pointcut="call(* $instanceof{java.sql.Statement}>execute*(..))">
<advice name="throwDeadlock”
aspect="SQLDeadlockExceptionInjector"/>
</bind>
Testing example
• To fine-grain it only for BankAccount class:
<bind pointcut="call(* $instanceof{java.sql.Statement}>execute*(..))
AND within(BankAccount)">
<advice name="throwDeadlock"
aspect="SQLDeadlockExceptionInjector"/>
</bind>
• To fine-grain for a specific method:
<bind pointcut="call(* $instanceof{java.sql.Statement}>execute*(..))
AND withincode(void BankAccount>withdraw(double))">
<advice name="throwDeadlock"
aspect="SQLDeadlockExceptionInjector"/>
</bind>
DesignByContract aspect
• This novel feature is a design technique
that lets us provide precise specifications
of valid arguments to methods, return
values, and valid states of objects
 Think Eiffel the programming language
• Specify pre-/post-conditions and invariants
by annotating the method or class
DesignByContract conditions
• Examples:
 Precondition
/* @@org.jboss.aspects.dbc.Dbc */
public class PreCondExample{
/** @@org.jboss.aspects.dbc.PreCond ({"$0 > 0"})
*/
public void squareRoot(int i)
{ .. }
}
 Postcondition (what must be true at end)
public class PostCondExample{
/** @@org.jboss.aspects.dbc.PostCond
({"$rtn=$0*$1"})
*/
public int multiply(int i, int j)
{ .. }
}
DesignByContract conditions
• Invariant: True before and after calling any public method
/** @@org.jboss.aspects.dbc.Dbc
* @@org.jboss.aspects.dbc.Invariant
({"$tgt.myString != null ||
$tgt.myString.length() > 0"})
*/
public class InvariantExample {
String myString;
public void setMyString(String s) {myString=s;}
}
DesignByContract usage
• Conditions may be defined for interfaces
 Enforced on all implementing classes
/* @@org.jboss.aspects.dbc.Dbc */
public interface RootInterface{
/*@@org.jboss.aspects.dbc.PreCond ({"$0 > 0"})
*/
public void someMethod(int i);
}
DesignByContract usage
• Defining the aspect
<aop>
<aspect
class="org.jboss.aspects.dbc.DesignByContractAspect"
scope="PER_JOINPOINT">
</aspect>
<bind pointcut="execution(*
$instanceof{@org.jboss.aspects.dbc.Dbc}->*(..)) OR
execution($instanceof{@org.jboss.aspects.dbc.Dbc}>new(..))">
<advice
aspect="org.jboss.aspects.dbc.DesignByContractAspect"
name="invoke"/>
</bind>
</aop>
Conclusion
• Who are the intended users for AOP?
 Application developers, to test code
• Inject errors, invoke validation routines
 Middleware developers
• Create transparent services
 System integrators / end-users
• Customize software to environment
 Easier to manage than with config files
• Rich environment for expansion, tweaking
 Unencumbered by OOP structure
 Case in Point: IBM
• “On-demand computing”
Conclusion
• JBoss has released AOP version 1.0.0 as
part of App Server v4.0.1
• Future development: undisclosed
 As a public company, JBoss does not reveal
future functionality
• JBoss has relationships with many
partners and system integrators, such as
HP and CA
Thank You.
Notes for myself