Packaging and Deploying AOP Applications to JBoss


This section provides an example of an application that covers the common scenarios of packaging and deploying AOP applications inside JBoss. The example is an online mortgage payment calculator application (see Figure 14.2).

Figure 14.2. The Mortgage Calculator sample application.


The servlet uses the Calculator class to calculate the monthly payment based on the loan principal, term, and interest rate.

 public class CalculatorServlet extends HttpServlet {   private Calculator cal = null;   public void init () throws ServletException {     cal = new Calculator ();   }   public void service(HttpServletRequest request,                       HttpServletResponse response)       throws IOException, ServletException {     response.setContentType("text/html");     ServletOutputStream out = response.getOutputStream();     String para = null;     int principal = 200000;     double rate = 8.0;     int term = 360;     double payment = 0.;     para = request.getParameter("principal");     if (para != null && para.length() > 0) {       principal = Integer.parseInt(para);     }     para = request.getParameter("rate");     if (para != null && para.length() > 0) {       rate = Double.parseDouble(para);     }         para = request.getParameter("term");     if (para != null && para.length() > 0) {       term = Integer.parseInt(para);     }     try {       payment = cal.getPayment(principal, rate, term);       // Write out the response in HTML     } catch (Throwable t) {       // Write out the error message in HTML     }   } } 

The Calculator class represents a POJO.:

 public class Calculator {   public Calculator () { }   public double getPayment (int principal, double rate,                             int term) {     rate = rate / 100.;     rate = rate / 12.;     double tmp = Math.pow(1.+rate, term);     return (principal * tmp * rate) / (tmp - 1.);   } } 

In the world of J2EE containers, the Calculator POJO cannot make use of container services because it does not follow the predefined component models (for example, it is not an EJB). But with JBoss AOP, you can apply EJB-style services as well as custom-developed container services to the POJO at runtime. The next two sections show how to do this.

Using Prepackaged Aspects

As discussed earlier in this chapter, JBoss AS 4 comes with several prepackaged aspects. One of the most useful aspects is the security aspect. It supports access control to any POJO methods, just as the EJB security service constrains access to EJB methods. In this section, an example demonstrates how to apply the prepackaged security aspect to the Calculator.getPayment() method in the Mortgage Calculator program.

Developing applications using the prepackaged aspects is easy. You can simply use a predefined annotation to mark up your source code and then use the annotation compiler to process the bytecode. In this example, the security domain is other, indicating that the usernames, passwords, and roles are stored in the users.properties and roles.properties files in the classpath. The security domain here has the same meaning as the security domain in EJB configuration file jboss.xml. Before the getPayment() method is invoked, the JBoss AOP security aspect transparently checks the user role, based on the username obtained by the servlet in the web context. Only users with the role Authorized can invoke the getPayment() method. The following is the annotated POJO code, using JDK 1.4style annotation:

 /**  * @@org.jboss.aspects.security.SecurityDomain ("other")  */ public class Calculator {   /**     * @@org.jboss.aspects.security.Unchecked     */   public Calculator () { }   /**     * @@org.jboss.aspects.security.Permissions ({"Authorized"})     */   public double getPayment (int principal, double rate,                             int term) {     rate = rate / 100.;     rate = rate / 12.;     double tmp = Math.pow(1.+rate, term);     return (principal * tmp * rate) / (tmp - 1.);   } } 

The following is the POJO code with JDK 5.0style annotation:

 @SecurityDomain ("other") public class Calculator {   @Unchecked   public Calculator () { }   @Permissions ({"Authorized"})   public double getPayment (int principal, double rate,                             int term) {     rate = rate / 100.;     rate = rate / 12.;     double tmp = Math.pow(1.+rate, term);     return (principal * tmp * rate) / (tmp - 1.);   } } 

No special packaging is required for deploying this application. You can just package the annotation-enhanced class files as regular Java classes in your .war or .ear applications. Figure 14.3 shows that the server refuses to invoke the Calculator. getPayment() method when the current user does not have the required Authorized role.

Figure 14.3. Detecting and rejecting users with inadequate security roles.


Notice that the application does not have a jboss-aop.xml file because the default annotation tags and bindings are already defined in the base-aop.xml file that comes with the jboss-aop.deployer package. The downside is that you cannot easily instrument your bytecode outside the server container. The easiest way to deploy this application is to enable the load-time AOP instrumentation in the server (see the section "Configuring the AOP Service," earlier in this chapter).

Developing Your Own Aspects

In addition to the prepackaged aspect services, JBoss AOP allows you to develop your own aspects to extend the AOP container services. The following example shows how to develop an aspect to limit the number of times the user can invoke certain POJO methods. When this aspect is applied to the Calculator object, you can make the mortgage calculator stop working after a certain number of queries (that is, you can put the calculator in the trial software mode).

As discussed earlier, the JBoss AOP aspect class is just a simple Java class. The advice method takes the Invocation object from the joinpoint as an argument and checks how many times it has been invoked. If it has been invoked more than five times, the aspect stops the invocation and throws an exception:

 package com.jboss.aspect; import org.jboss.aop.joinpoint.Invocation; public class TrialLimitAspect {   private static int count = 0;   public Object checkLimit (Invocation invocation)                                    throws Throwable {     System.out.println("Check whether the trial limit is reached");     count++;     if (count < 5) {       return invocation.invokeNext();     } else {       throw new Exception("Hit the maximum access count");     }   } } 

As with prepackaged aspects, the easiest way to bind a custom aspect to applications is to use annotations. You can define custom annotations for an aspect and then publish them as part of the service API. In JBoss AOP, each annotation is a Java interface. The following trialLimit interface defines the trialLimit annotation tag:

 package com.jboss.aspect; public interface TrialLimit { } 

In the jboss-aop.xml file, you can specify the binding between the annotation tag and the advice method:

 <aop>   <aspect            scope="PER_VM"/>   <bind pointcut="execution(* *->@com.jboss.aspect.TrialLimit(..))">     <advice name="checkLimit"             aspect="com.jboss.aspect.TrialLimitAspect"/>   </bind> </aop> 

Finally, in the application code, you just need to tag your methods, which need invocation limit control, with the annotation, as you do with prepackaged aspects. Notice the second tag on the getPayment() method:

 /**  * @@org.jboss.aspects.security.SecurityDomain ("other")  */ public class Calculator {   /**     * @@org.jboss.aspects.security.Unchecked     */   public Calculator () { }   /**     * @@org.jboss.aspects.security.Permissions ({"Authorized"})     * @@com.jboss.aspect.TrialLimit     */   public double getPayment (int principal, double rate,                             int term) {     rate = rate / 100.;     rate = rate / 12.;     double tmp = Math.pow(1.+rate, term);     return (principal * tmp * rate) / (tmp - 1.);   } } 

Figure 14.4 shows the servlet, displaying an error message when the invocation limit has been reached.

Figure 14.4. The custom aspect detecting that the user has reached the invocation limit for this POJO method.


Packaging and Deploying Custom Aspects

To deploy the TRialLimitAspect aspect or any other custom aspect, you have to package the aspect properly so that the JBoss application server can recognize it as an aspect library. You have the following two options:

  • You can package the aspect classes, annotation interfaces, and configuration files together in a JAR archive file with the filename extension .aop. The jboss-aop.xml and metadata.xml files must reside in the META-INF directory in the .aop JAR archive. In this example, you can bundle the .aop file with the .war file in the same .jar repository (see Figure 14.5), and then you can deploy the .jar file as a single application. Or you can deploy them side-by-side on the server. If you use custom aspects in EJB applications, you can include the .aop file directly in your .ear file.

    Figure 14.5. Packaging the aspect library, binding configuration file, and web application into one JAR file for easy deployment.


  • You can simply package the aspect classes and annotation interfaces in a .jar file and then specify the binding in an *-aop.xml file. You can copy the .jar file and the *-aop.xml files into the deploy directory (see Figure 14.6). The aspects and their bindings become available to all applications deployed in this server.

    Figure 14.6. Deploying the aspect library, binding configuration file, and web application separately.


The sample application for this chapter uses the first approach and builds a trialLimitAspect.aop file and a MortgageCalculator.war file side-by-side. All other applications deployed in the server can make use of the aspect in the trialLimitAspect.aop file as well.



JBoss 4. 0(c) The Official Guide
JBoss 4.0 - The Official Guide
ISBN: B003D7JU58
EAN: N/A
Year: 2006
Pages: 137

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net