Skip to main content

More about Practical AOP and Transparent Remoting

Posted by mister__m on January 4, 2005 at 10:53 AM PST

I am glad my original post about Practical AOP and Transparent Remoting has received polite and smart comments against it. This is definitely a nice way to get the discussion about AOP going! Here are my answers to these comments.

First of all, cajo said that "this is a perfect example of why I fall into what you call your third AOP viewpoint. As you said, magic happens; but it is also totally invisible from the actual source code. I can't imagine how one would debug a complex application." I am sure this is a reason why many developers are concerned about AOP adoption. But let's address this question to see if this point should prevent us from using AOP.

First, how do you debug such application? If you simply use your IDE "Step Into" debugging functionality and you happen to have genesis sources available, your debugger will stop at the advice's first line. And then, everything will be simple to understand. But maybe the real question is: how would I guess I should step into at that line? To answer this question, we just need to think about how we decide to use step into when debugging our OO applications.

If you have a snippet like:

public void aMethod(SomeClass o) {
   o.someMethod();
}

You already cannot assume you should look for someMethod() implementation in SomeClass in this simple example. Why? Because you might be dealing with a subclass or maybe a proxy. And if SomeClass is an interface and the instance you received is a dynamic proxy, it becomes even harder to debug. So, if there's any chance you're dealing with a polymorphic call today, you already have to guess whether the code being executed belongs to SomeClass or is defined on another class. "Hey, but I don't have to guess; I can use Step Into today", someone might say. And that's just what I said a few lines above. You should use Step Into in these cases to be sure what code is actually being executed. The only new thing with AOP is that it may happen with any method, but it is not different from today.

Besides that, either your aspects should affect well-defined points in your code or you should use a tool. AspectWerkz provides an Eclipse plugin that helps you to see which methods are affected by advices, for example.

Then, cajo proceeds:

Consider operator overloading: Many argued against its inclusion in Java, because it could make the source look less obvious.

To me, this source looks far less obvious.

Well, except for String concatenation tricks - which shouldn't exist for consistency, anyway -, I agree about operator overloading because it already has just one meaning. But as I showed above, a method call is already "trickier".

Another interesting response came from jhook. He begins:

I can't necessarily argue with what Michael is trying to accomplish, just in how it's being accomplished. The problem with many of these AOP implementations is that you are modifying the behavior of an object for everyone. The behavior of RemoteClass is intrinsic, adding a client's ability to remote 'helloWorld' is extrinsic to RemoteClass and IMHO shouldn't be applied for all clients of RemoteClass (at compile time).

Some of that's true, indeed. For this specific case, my intent was that every RemoteClass client had to access it through the aspect. But it only affects clients that have access to the weaved version of the class. So, in the server side, we keep a "regular" version of it and no remoting is necessary. This is one approach to actually do what jhook suggested: use the class version you want.

Another approach is to change your pointcut to intercept calls to the method and not changing its execution as the default aop.xml that comes with genesis empty-project does. That's the beauty of AOP: this behaviour is actually extrinsic to the class, since your configuration will determine whether method execution, call or none will be affected by which advices you choose.

The last comment I would like to reply to have been made by ablperez. It says:

A cleaner example of AOP's power would have been taking a POJO and making it transactional. Objects that are remotable should clearly relflect that. This example commits the fallacy "The network is reliable" from the eight distributed computing fallacies. A well defined remotable object should declare to throw a remote exception. IMHO remoting is not something you want to hide.

Well, that's debatable. How would you handle the RemoteException? Rethrow it in every method that calls this class? Write tons of try/catch blocks spread throughout your codebase? A cleaner approach would be to handle it once, in one single place. Since Thinlet - and therefore genesis - already defines a single point for handling exceptions, you can do it once in a base class. However, if you do think it's nice to be more explicit, just add a throws java.rmi.RemoteException to the method's signature and handle it as you wish. The exception will be thrown as you would expect.

It's important to mention that genesis default project structure is targeted to intranet environments, where bandwidth shouldn't be a problem most of the time. Besides that, a timeout aspect is applied to every remote call to make sure it either completes timely or a timeout exception is thrown. So it actually expects delays to happen. The default aspect doesn't do any fancy stuff, such as displaying a wait dialog or something like that. This should be customized on a project basis.

I hope we can keep this healthy discussion going, since I think it just helps the community as a whole. By the way, a new genesis release, 0.2-beta2, is now available. Its documentation is available if you are interested. I'll be saying more about AOP soon. Stay tuned ;-)

Related Topics >>