Val's Blog
Lots of stuff for Web 2.0 freaks and Java addicts
Feeds RSS | Atom | RDF
 
 
Albert Einstein: "Intellectuals solve problems: geniuses prevent them."
[ Login ]

June 2004
SunMonTueWedThuFriSat
   1  2  3  4  5 
 6  7  8  9  10  11  12 
 13  14  15  16  17  18  19 
 20  21  22  23  24  25  26 
 27  28  29  30    
May  |  Today  |  Jul
XML Feeds   Subscribe with Bloglines

Javaranch Sheriff   My LinkedIn Profile
Drop me a line or two   Bloglines Blogroll
JavaRSS   Referers
How cool are you?   My Reviews

Next trips...
SpringOne 2008 (Jun 11-12, 08)
Ajax Exp. 2008 (Sep 29-Oct 1, 08)
Top 10 entries (#hits)
(As of Nov 30, 2007)


Top 10 entries (#hits/day)
Come Back (5.032)
(As of Nov 30, 2007)
Recent Blog Entries
Recent Blog Comments
Re: Review of "Marketing Management 12th"
i know marketing management by kotler is good book but the problem is that the management part of this book is totally missing as fare as i know managemet is complete different subject and it should not be mixed i am student of MBA i was looking at ass...

Re: Review of "Pro Spring"
Using simple POJOs + factories without Spring for "echo" and "counter" would be a lot more easier. No need to write those XML files... So, in this case using Spring makes me write a lot more code... (OK, you can generate everything with the help of And...

pls urgent
Hi I am trying to generate the word doc but i m not understanding wats happening any one pls figure it out /* * WordAPI.java * * Created on May 30, 2006, 10:50 AM * * To change this template, choose Tools | Template Manager * and open the te...
Archives (# entries)
Links
Other Blogs
Other Blogs

Reviewing
Reading
Locations of visitors to this page
What they once said...
 

Ever wondered whether Java lets you play around with method "pointers" as C or C++ do? The Java Reflection API provides the necessary support for handling any high-level Java construct (class, method, field, etc) as a normal Java object that you can inspect and manipulate.

A couple of days ago, David Shay explained how he came to know about this technique and commented on the runtime overhead due to reflection. I won't go into that, I just would like to show one concrete example of how method pointers could be used in practice. Since every problem usually has many solutions, the code example I'm going to discuss below is also implementable without reflection, of course :)

For this example, I have been inspired by Lars Haendel's tutorial on C/C++ function pointers. The code shown in the table below is an equivalent Java implementation of his code with some enhancements that I describe hereafter.

1.  import java.io.*;
2.  import java.lang.reflect.Method;
3.  public class TestMethodPtr {
4.        
5.      public static float plus(float left, float right) {
6.              return left + right;
7.      }
8.
9.      public static float minus(float left, float right) {
10.             return left - right;
11.     }
12.     
13.     private static Method getOperation(char opCode) throws Exception {
14.             if (opCode == '+') return getMethod("plus");
15.             if (opCode == '-') return getMethod("minus");
16.             return null;
17.     }
18.     
19.     private static Method getMethod(String name) throws Exception {
20.             Class cl = TestMethodPtr.class;
21.             Class[] params = new Class[] {Float.TYPE, Float.TYPE};
22.             return cl.getMethod(name, params);
23.     }
24.     
25.     private static char readChar() throws IOException {
26.             BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
27.             System.out.print("Type in the operation (+/-): ");
28.             return (char) in.read();
29.     }
30.     
31.     public static void main(String[] args) throws Exception {
32.             // define a method pointer and the arguments
33.             Method methodPtr;
34.             Object[] arguments = {new Float(2f), new Float(4f)};
35.   
36.             while (true) {
37.                     // get the method pointer
38.                     methodPtr = getOperation(readChar());
39.                     
40.                     if (methodPtr == null) {
41.                             System.out.println("Bye bye!!");
42.                             break;
43.                     }
44.                     
45.                     // call the method using the pointer
46.                     System.out.println("  Result: " + methodPtr.invoke(null, arguments));
47.             }
48.        }
49. }
  
Output:
D:\>run
Type in the operation (+/-): +
  Result: 6.0
Type in the operation (+/-): +
  Result: 6.0
Type in the operation (+/-): -
  Result: -2.0
Type in the operation (+/-): -
  Result: -2.0
Type in the operation (+/-): +
  Result: 6.0
Type in the operation (+/-): q
Bye bye!!

D:\>
 

The goal of the TestMethodPtr class is to ask the user what kind of operation she would like to perform. If she wants to do an addition, she types in '+' (without the quotes) at the prompt. For a subtraction, she will input '-' instead (see method readChar(), lines 25-29). Any other character will shut down the program. Upon receiving a character, the program will determine which method should be invoked: plus() for '+' and minus() for '-' (see method getOperation(), lines 13-17). Finally, when the appropriate method is returned, it is always invoked with the same fixed argument values, namely 2 and 4. Agreed, this is not really useful, but letting the user specify the arguments would have unnecessarily complicated the example without bringing much more value. This example just aims at demonstrating the parallel between C/C++ function pointers and Java Method references. As I mentioned before, the same result can be achieved without method pointers as depicted in the code below.

1.  import java.io.*;
2.  import java.lang.reflect.Method;
3.  public class TestMethodPtr {
4.        
5.      public static float plus(float left, float right) {
6.              return left + right;
7.      }
8.
9.      public static float minus(float left, float right) {
10.             return left - right;
11.     }
12.     
13.     private static char readChar() throws IOException {
14.             BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
15.             System.out.print("Type in the operation (+/-): ");
16.             return (char) in.read();
17.     }
18.     
19.     public static void main(String[] args) throws Exception {
20.             while (true) {
21.                 char opCode = readChar();
22.                 if (opCode == '+') {
23.                     System.out.println("  Result: " + plus(2f, 4f));
24.                 } else if (opCode == '-') {
25.                     System.out.println("  Result: " + minus(2f, 4f));
26.                 } else {
27.                     System.out.println("Bye bye!!");
28.                     break;
29.                 }
30.             }
31.     }
32. }
  
Output:
D:\>run
Type in the operation (+/-): +
  Result: 6.0
Type in the operation (+/-): +
  Result: 6.0
Type in the operation (+/-): -
  Result: -2.0
Type in the operation (+/-): -
  Result: -2.0
Type in the operation (+/-): +
  Result: 6.0
Type in the operation (+/-): q
Bye bye!!

D:\>
 

Personally, I have very seldomly encountered the case where I needed to pass references to Method objects around in my applications. As I said in another blog, if you need to do this, you probably have to rethink your design. It's not because a feature is available that you must use it blindly.

During the last three years, many different aspect-oriented technologies (AspectJ, AspectWerkz, JBoss AOP and Co) have been developed and some of them have started gaining a broad community and industry acceptance.

While the benefits of using AO techniques in conjunction with existing paradigms, such as OO, become clear to more and more people everyday, there are still "tiny details" (code invasiveness, over-modularization, performance, security, complexity, etc) that prevent AO technologies from being fearlessly and widely deployed and used. I'm pretty confident that in the future IDEs will leverage best practices and patterns to provide developers with better support for dealing with these issues. It is pretty safe to say that the success of AOP heavily depends on outstanding tool support and is only a matter of time now.

On the other hand, there are some big actors that we haven't heard of much. While IBM has announced that they officially back AOP, that BEA supports AspectWerkz and that Sun has decided to host an AOP panel at JavaOne 04, one could wonder where Microsoft stands on the AOP scene, and if they are even interested in AOP...

If you browse a little on Microsoft's website, all you will find is a link to an old, yet interesting, article titled "AOP Enables Better Code Encapsulation and Reuse" by Dharma Shukla, Simon Fell, and Chris Sells published in the March 2002 edition of the MSDN magazine. On Microsoft Research's website, you can also dig out the Aspect.NET project, which aims at providing a AOP framework for .NET. Apart form that, not much to report under Microsoft's sun (no pun intended). However, it is no secret that Intentional Software Corp., founded by Microsoft's former Chief Architect Charles Simonyi and AspectJ's lead developer Gregor Kiczales, is "active" in the AOP arena. It might be interesting to see what comes out of that venture.

Recently, Dion Almaer published a blog entry titled Anders Hejlsberg and AOP which actually hints that Microsoft is not just "knowing" the path but might also be willing to walk it. It would be cool to see what comes out of those "discussions".

When I published my somewhat critical review of "Hardcore Java", I kind of expected that the author would drop into the Book Reviews forum at Javaranch.com to have a friendly discussion about the book.

During the discussion, I have found that Robert Simmons Jr is indeed a very nice guy who is truly open to critics and gladly accepts *constructive* comments, which is not true of all authors out there. An author's openness to critics and comments is undoubtedly an important fact to take into account when reviewing a book. Unfortunately, you often get to know the man after reading his first book...

In the discussion, Robert said that he would include a chapter on classloaders, another on package management and some other cool stuff in the second edition, should there be one. I'm trully looking forward to reading that new stuff :) In the meantime, Vivek has opened the good old debate on the final keyword... You are welcome to share your thoughts about that.

For those of you who intend to take the AOP pill sooner or later, it is important to know that there are two main trends out there, namely solutions that achieve AOP by:

  1. extending existing languages (AspectJ & Co)
  2. combining existing technologies without extending them (AspectWerkz & Co)

When AOP adoption is at stake, choosing one or the other solution may not be as straightforward as it seems. In this blog, I will try to make an objective, yet non-exhaustive, comparison between the two of the biggest actors on the AOP scene, namely, AspectJ and AspectWerkz.

The AspectJ community has created a seamless extension to the Java language with a bunch (> 20) of new keywords (aspect, pointcut, etc) as well as a compiler that weaves aspect definitions into your application classes and spits out normal Java bytecode that can be executed on any JVM. AspectWerkz has favored a no-extension approach and uses XML and the conventional Java language syntax and semantics for bringing aspects into the Java language.

In AspectWerkz, aspects are Java classes (+ attribute @Aspect), advices are Java methods (+ attributes @Around, @Before, @After) and introductions are represented by static inner classes (+ attribute @Introduce) or normal Java fields (+ attribute @Implements). Pointcut definitions are either written in XML definition files or within the aspect class as fields (+ attribute @Expression). All these attributes will probably be replaced by metadata annotations when JDK 1.5 comes out. Both AspectJ and AspectWerkz use a very similar pattern language for picking out join points and they both support the same kinds of pointcut compositions (!, &&, ||) and definitions (call, execution, set, etc). However, it is worth noting that AspectJ provides a number of pointcuts that have no direct equivalent in AspectWerkz, such as within(), withincode(), initialization(), staticinitialization(), preinitialization(), adviceexecution(), cflowbelow(), etc.

If you decide to go with the first solution, you will need to integrate the AspectJ compiler into both your development environment and process. Moreover, you will have to learn the new syntax and semantics AspectJ adds to the Java language. While AspectJ provides several modules that you can plug into your favorite IDEs, it might not always be the best solution depending on how open your company is when it comes to adopting new tools and/or languages. In contrary, AspectWerkz allows one to define aspects using conventional Java syntax and semantics, i.e., all aspect-related code is declared using javadoc-like attributes written in class, field and method comments which might lower the learning curve necessary to get your first advanced HelloWorld running.

Now, I am going to discuss an example (shown in Figure 1 below) taken from the AspectJ Programming Guide that I have sort of re-implemented with AspectWerkz in order to provide a very basic comparison between both solutions. Of course, the example is pretty academic and not really complicated, but it's a good start... Also, note that the Screen class is not shown on the figure.


Figure 1. The PointObserving aspect in AspectJ and AspectWerkz
(Click on the image for the full view)

The first thing that comes to mind when seeing this figure is that the AspectJ code is more concise. For instance, there is a code overhead in AspectWerkz's afterChanges() method for retrieving the Point argument that is directly available in AspectJ. Also, the field introduction (observers Vector) has to be done with a Mixin class in AspectWerkz while AspectJ only requires a simple field declaration. The AspectWerkz code (counting the comments) is almost twice as long as the AspectJ code.

I don't mind the Mixin stuff for implementation introductions, but the supplementary line for retrieving the context variables in the advice do bother me actually. Why AspectWerkz does not consider letting one specify the pointcut context variables as parameters to the advice method? This would be quite equivalent to AspectJ: we would be able to keep the JoinPoint parameter (AspectJ's thisJoinPoint and thisJoinPointStaticPart) plus we would get direct access to the context variables as shown below.

  /**
   * @After changes
   */
  public void afterChanges(final JoinPoint jp, Point p) throws Throwable {
    Iterator iter = p.observers.iterator();
    while (iter.hasNext()) {
      updateObserver(p, (Screen) iter.next());
    }
  }
  

Another thing that kind of annoys me is that AspectWerkz has only a conceptual notion of abstract pointcuts. In AspectWerkz's example on Aspect inheritance, we can see that the abstract aspect AbstractLoggingAspect's metadata references "abstract" pointcuts (methodsToLog1, methodsToLog2, methodsToLog3, etc) that can actually only be declared in the concrete sub-aspect LoggingAspect since Java has no notion of abstract fields. This makes it a bit difficult to see all the pointcuts that have to be defined in the concrete aspects in one glance.

AspectJ also provides other inter-type declarations(declare warning, declare error, declare soft, declare parents, declare precedence) that facilitate development but that I haven't been able to find anywhere in AspectWerkz yet. If someone knows the techniques for implementing them in AspectWerkz, I'd be really happy to learn them. Thanks in advance :) On the other hand, AspectWerks allows one to define custom attributes (@@ custom attributes) which AspectJ doesn't. Again, I think that JDK 1.5 will provide the necessary support for getting rid of this difference.

I have been using AspectJ since the first beta versions and I have always been quite happy with it. However, even though AspectJ excels at type-based crosscutting, I still think that it lacks proper techniques for achieving *true* instance-based crosscutting. JBoss AOP and Spring (which I haven't talked about in this blog) are said to achieve this goal but I'm not completely satisfied with those solutions. I'm still looking into how AspectWerkz could provide a better solution to my problem. I'll probably write an update about this problematic in the near future.

As a conclusion I would like to stress that my goal was neither to promote one solution over the other nor to provide an exhaustive comparison between AspectJ and AspectWerkz. There are many other details about both technologies that I haven't talked about. I just wanted to highlight some differences and similarities that I have found between both solutions. Finally, if any information that I have stated in this blog is innacurate, please do let me know.


Update: Thanks to Jonas Bonér for spotting one mistake in the AspectWerkz code.

 
About this Blog