Saturday, 31 March 2012

JavaEE Revisits Design Patterns: Aspects (Interceptor)

I have written some blogs on aspects years ago. AspectJ and Spring Aspects have served well for long years. However they may not be the first choice when it comes to JavaEE world. I have written several posts on how JavaEE implements several design patterns (singleton, dependency injection, factory, observer, asyncronous) and aspects is not an exception.

Interceptors are very easy to implement in JavaEE without any xml configuration. Lets go back to our example given in the previous posts and start with adding a new plain class. Since we already used logging as an example for the observer post, lets assume now we need to implement a security mechanism on our existing service.


package com.devchronicles.observer;


import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;


/**
 *
 * @author murat
 */
public class SecurityInterceptor {
    
    @AroundInvoke
    public Object doSecurityCheck(InvocationContext context) throws Exception{
        System.out.println(context.getMethod().getName());
        
        return context.proceed();
    }
}


As mentioned before the class is a plain java class and does not implement or extend any other class. Here the @AroundInvoke annotation does the magic. The methods marked with this annotation need to return an Object and get a InvocationContext parameter. InvocationContext gives access to method and parameter info and values as well as ability to change them. In this example we simply get the method name. Another important point is to call context.proceed() to continue execution process.

To put our interceptor in action we need to add an annotation to our target classes which is the EventService bean from the previous posts.


package com.devchronicles.observer;


import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.enterprise.event.Event;
import javax.inject.Inject;
import javax.interceptor.Interceptors;


/**
 *
 * @author murat
 */
@Interceptors(SecurityInterceptor.class)
@Stateless
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class EventService {
    @Inject
    private String message;
    
    @Inject 
    Event<String> event;
    
    public void startService(){
        System.out.println("start service call "+message);
        event.fire("this is my "+message);
        System.out.println("done...");
    }
}

Don't worry about the grey and specially the lighter grey parts which comes from the previous posts. The @Interceptor annotation is the only code we need to add to make our existing class a target for our interceptor and there is no other configuration need to be done!


Monday, 19 March 2012

Android merges back to Linux

Finally the day come that Android merges back to Linux repositories. Android Kernel was forked from Linux but failed to merge back due to disagreement between developers from both projects. With the latest news from lwn.net and kernelnewbies.org it has been stated that various Android subsystems and features have already been merged, and more will follow in the future.

Android has taken linux somewhere no linux fan could ever imagine, today even Microsoft is building applications for Android which actually made them built applications for linux. Avery good news for both parties for the future of both projects.

Sunday, 11 March 2012

Session Sharing between Java Web Applications

We had been asked to share sessions between different war files several times on different projects. This requests vary from just asking our opinion to trying to persuade us to do it by citing vendor documentations. 

Those who had watched Star Wars before, would probably remember Darth Sidious's famous saying:
 Dark side of the force is the pathway to many abilities, some considered to be... unnatural.
However, only Siths tend to use the dark side. Jedis instead follow the Jedi code. Back to our topic, if we would need a code for the light side on the Java world, that should be the Java Specs by the JCP. Although most vendor implementations would let you share sessions by their custom settings.
Sharing sessions between web applications will override the following JSRs, thus make your application not compatible with Java Standarts. 

Servlet Speciation - "SRV.7.3 Session Scope HttpSession objects must be scoped at the application (or servlet context) level. The underlying mechanism, such as the cookie used to establish the session, can be the same for different contexts, but the object referenced, including the attributes in that object, must never be shared between contexts by the container."  

Servlet Speciation - "SRV.9.2 Relationship to ServletContext 
The servlet container must enforce a one to one correspondence between a web application and a ServletContext. A ServletContext object provides a servlet with its view of the application.
In order to share data across web applications you'll need to implement your own scheme. If it's a small amount of data, you could store it in a cookie that either web application could retrieve. If it's a large amount of data, you could store it in a database, then set a token in a cookie to identify the client and retrieve the data."


JavaEE Specification - Removal of class loader barriers to share session data will impede each component to define its security requirements through a deployment descriptor.  Components will be accessible from each other disregarding deployment descriptors (EE3.6 EE3.3).

Sharing sessions between web application would violate those items both in Servlet and JavaEE specifications. However, there are different ways to pass data between web applications without breaking the rules.

First and easiest solution would be cookies. It is possible to store simple and small data on the client side using cookies.  The session cookies can be encrypted and can store small amount of textual data. Session cookies can be used to store non-sensitive session information, they can be share between a group of applications using context paths.

If the data needed to pass is more complex and sensitive there are third party solutions from different vendors or MemCached.  These technologies enables session sharing and management across different web applications, domains and heterogeneous application servers; They are typically distributed for scalability, availability, reliability and performance to in-memory session management and storage; They support all the mainstream application servers such as Oracle WebLogic Server, IBM WebSphere, Tomcat., Oracle WebLogic Portal, etc. 

Whatever solution you choose to implement, always try to be compatible with Java specs although some vendors would give you opportunity not to do so. Keep in mind coupling with a vendor by breaking the rules would lead you to a different path which might considered to be... unnatural.