14 Jan 2012

Hot Code Replace in Eclipse, or how to boost the debugging process

Here are some ideas to optimize the build&test process within Eclipse, regarding Web projects.


First of all, if your are developing new features that take longer to code, consider disabling the "Build automatically" check in Eclipse. Continuous recompilation just adds unnecesary overhead to our computer. And if memory is scarce or, as it happens often, we have an additional myriad of applications open at the same time, it consumes resources and slows down the system. After all, Ctrl+B does a incremental backup as well, but at user's will.


On the other side, if we are debugging and making many small changes, Build Automatically is the recommended option, as we will see afterwards.


Secondly, if you are working on a Web project, disable autoreloading. By default, projects compiled get automatically published and in turn, projects configured (i.e. on a Tomcat server) get automatically reloaded. That means, ¡ the server is shut down and restarted again ! This is often cumbersome, specially if we are working with a system which takes time to get up and running. Let the developer decide when he wants the server to be restarted.


To disable automatic reloading, do the following:
- Double-click on the server.
- Click on the Modules tab.
- From the listed modules, select the one we are working on.
- Click on "Edit".
In the popup window shown, unselect "Auto-reloading enabled":




Publishing (to the server) gets done automatically after compilation, which is fine since we normally want to publish after a successful compilation and if not, it is a fast operation anyway. This is also ok if we modify JSP pages.


The third aspect of this comes when we are debugging and want to make many small changes that we want to test frequently. How can we avoid restarting the system after every change? The answer comes from the Hot Code Replace (HCR) feature of Eclipse. HCR allows to replace one class for another as long as we don't change its signature, that is, we don't declare new methods or fields. But if we just modify the body of a method, then normally Eclipse will rebuild the class, publish it and restart the debugger at the beginning of the method (provided we had stopped on a breakpoint inside this method). This is much faster, don't you think?


Invest 5 minutes of your time to test these settings, and you will get a fast payback!



Using AOP to control authorized callers of a service


Some days ago, I came across a problem regarding service management and security.
Let me first introduce our development background. We deliver libraries which are used both by us and by third parties to develop applications. They are based on Spring (2.5.6) and Hibernate (3.4). Moreover, the libraries access external Web Services and wrap them with additional functionality like data cache, database updates and so on. One of these libraries was to be accessed via a Spring service (say A) which was in charge of calling another service (let us call it B) and making additional operations. The point was, we didn't want developers to inject service B directly into their classes and call its methods, but instead use service A.

One solution could have been to publish service "B" with some kind of weird name so only service A would know and use it. But since we delivered the source code too, this solution simply was not secure enough. From the Java perspective, perhaps setting all methods in service "B" to "protected" could have been an option, provided both classes resided in the same package; but this was not the case, and refactoring one of the classes and moving it into a different package was not an option either.

After considering also other solutions like using Spring Security, I finally decided to use AOP.

AOP gives us a very elegant and straightforward answer to our requirement. And, even better, it sounds natural. Because remember, the question raised was: how can I prevent developers from accessing service B directly? And the most natural answer could be, "by avoiding access to its methods whenever the call is not coming from one of the allowed classes". In other words, check who the caller is and if it is not service A, ban it and return null or throw an exception.

So let's get to work. Spring supports AOP in several ways, including AOP Alliance's "MethodInterceptors". A class implementing this interface is designed to intercept calls to defined methods. Therefore, it implements a method, "invoke", which will receive the calling information (called class and method names, as well as arguments), process it and decide whether it permits the call to be carried out or be intercepted. 

In our case, the invoke() method will check out who the caller is, and compare its name with serviceA's class name. If they match, the proceed() method will be called, reaching its primary destination. If not, an exception will be raised and an explanatory message be printed in the log archives.

What we must develop first is a class implementing MethodInterceptor. Let's call it SecurityInterceptor, for it is going to perform security checks. This class would look similar to:

@Service
public class SecurityInterceptor implements MethodInterceptor  {
    
    private static Log LOG = LogFactory.getLog(SecurityInterceptor.class);
    
    private static final String AUTHORIZED_CALLER = "com.whattepasa.Caller"; // Could also be defined in a config file

    public Object invoke(MethodInvocation invocacion) throws Throwable {
        StackTraceElement[] trace = Thread.currentThread().getStackTrace();
        if (!checkStack(AUTHORIZED_CALLER, trace))  {
            LOG.error("Access denied");
            return null;
        }
        else {
            return invocacion.proceed();
        }
    }
    
    private boolean checkStack(String className, StackTraceElement[] trace)  {
        for (StackTraceElement traceElement : trace)  {
            if (traceElement.getClassName().indexOf(className)!=-1) {
                return true;
            }
        }
        return false;
    }
}

This code will work with Java 5 and above. Note that the class is annotated as a Spring service (@Service)

As the call does not necessarily come directly from the allowed class, since there might exist other interceptors who would interfere the original call, we must loop back through the stack, looking for the expected calling class one by one. This might slow down operations a bit but the overall impact is very low since it's just a fast loop in memory; and specially because we will invoke this interceptor only when there is a pointcut match. 

Now wait, what is a pointcut? Simply speaking, it is an expression describing when do we want the interceptor to be invoked. Pointcuts in Spring AOP follow the same syntax as in AspectJ. Not all expressions are supported by Spring, but quite a big subset of them.

In our case, the pointcut expression would be defined as follows:

<aop:pointcut expression="execution(* com.whattepasa.ServiceB.*(..))" id="security" />

Which can be read as "match all executions of any method of the ServiceB interface / class". Exactly what we want.

We must relate the pointcut (when) with the interceptor (what); that's why we added the @Service annotation to our interceptor (in AOP notation, such an interceptor is called an "advice"). Using XML-style declarations, the final configuration would look something like this:

<aop:config>
     <aop:pointcut expression="execution(* com.whattepasa.ServiceB.*(..))"              id="security" />
<aop:advisor advice-ref="securityInterceptor" pointcut-ref="security"/>
</aop:config>


And that's all it takes!

Of course, this is just an introduction. The astute reader will devise an easy way to extend the interceptor as to protect more classes, each one with a list of allowed callers. This could also be easily configured via Spring configuration files, therefore defining a very powerful way of controlling who can call which service and in which way.

For more information:

Enjoy!