Entries Tagged 'Java' ↓

Stripes presentation at TJUG

Last week at TJUG, our local Java User Group, I had a short presentation called “Stripes – Painless Java Web Development”, introducing (obviously) Stripes. Slides can be downloaded here.

We also had a chance to take a look at Eclipse RAP in another presentation by Gabriel Ciuloaica – “From Eclipse RCP to RAP”.

Many thanks to Gabi Pop who always takes care of planning and organizing the TJUG meetings.

Spring by examples – RMI

RMI is just one of the strategies that you can choose from when you want to implement remoting in your Spring application. At the moment, Spring provides support for Hessian, Burlap, RMI, Web services and an own HTTP remoting solution. All of these remoting strategies were designed so they can share a common configuration style allowing you to manage the exporting and accessing method from outside your business code, in the well known non-intrusive Spring manner. This means that Spring offers a POJO-based programming model for both your server and client, no matter which remoting solution you choose. The reference documentation regarding the remoting features of Spring is available here.

For now we will take a look at how Spring handles RMI while peeking into the code of a small demo application. Our example contains a simple delivery service exposed through a DeliveryServiceIntf interface that has two methods for handling Delivery objects. Below is some of the code for these objects.

public class Delivery implements Serializable {

    private String requesterName;
    private Date deliveryDate;

    public Delivery(String requesterName, Date deliveryDate) {
        this.requesterName = requesterName;
        this.deliveryDate = deliveryDate;
    }
    ...
}

public interface DeliveryServiceIntf {

    void newDelivery(Delivery delivery);

    List getDeliveries();

}

As you can see, the service interface does not need to extend the java.rmi.Remote in order to be used as an RMI service. Also, it’s remotely accessible methods don’t need to throw java.rmi.RemoteException. This is a Spring enhancement that applies to all it’s remoting solutions, not just to RMI. But this is no reason to get scared, because Spring will manage the invocation failure in it’s own fashion by throwing a org.springframework.remoting.RemoteAccessException. This is an unchecked exception so the client can decide if it wants to catch and handle this exception or just ignore it when it’s occurrence it’s considered fatal. This is however Spring’s recommended approach, but you can also expose traditional RMI implementations with Spring. Actually, this is an important issue that you should consider and analyze when remoting with Spring. While both traditional and Spring-managed RMI clients can access a traditional RMI server implementation exported through Spring, only a Spring client will be able to access a Spring exported RMI service that uses a POJO-based model.
Getting back to our example, we have below the implementation of our service which I tried to keep as simple as possible:

public class DeliveryServiceImpl implements DeliveryServiceIntf {

    private List deliveries = new ArrayList();

    public void newDelivery(Delivery delivery) {
        deliveries.add(delivery);
    }

    public List getDeliveries() {
        return deliveries;
    }
}

After we have everything implemented on the server side, we need to configure Spring to export the service through RMI. The following Spring configuration snippet does just that.

    <bean id="deliveryService" class="com.test.rmi.server.DeliveryServiceImpl">        
    </bean>

    <bean class="org.springframework.remoting.rmi.RmiServiceExporter">
        <property name="serviceName" value="delivery-service"/>
        <property name="service" ref="deliveryService"/>
        <property name="serviceInterface" value="com.test.rmi.common.DeliveryServiceIntf"/>
        <property name="registryPort" value="1234"/>
    </bean>

This is the point where we can choose which one of Spring’s remoting solutions we want to adopt. In our case we will use org.springframework.remoting.rmi.RmiServiceExporter which will also manage the RMI registry for us. The serviceName and registryPort properties are RMI specific settings that will constitute the information the client side needs to access our service. The URL for the service in this case will look something like rmi://hostname:1234/delivery-service. The serviceInterface property indicates the POJO whose methods will be the subject of RMI invoking and the service property references a bean implementing the business logic of the service.
At this point, having all up-and-running on the server side requires a small amount of effort and it only consists of classic Spring context initialization.

public class RmiServerTest {

    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("com/test/rmi/server/rmi-server-context.xml");        
    }
}

Now let’s see how does it work on the client side and how should we proceed to access the remote service. Here is actually a little bit easier because everything relies on the Spring bean configuration file, as seen below, while the rest of the code is pretty straightforward.

    <bean id="deliveryService" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
        <property name="serviceUrl" value="rmi://localhost:1234/delivery-service"/>
        <property name="serviceInterface" value="com.test.rmi.common.DeliveryServiceIntf"/>
    </bean>

As you can see, we just need to define the deliveryService bean of class org.springframework.remoting.rmi.RmiProxyFactoryBean. This will indicate Spring that the deliveryService bean will actually be a proxy accessing the remote service at the URL rmi://localhost:1234/delivery-service, and that the business logic of the service will be used by the client through the methods of the DeliveryServiceIntf interface.
Accessing this bean will create a proxy that we can cast to the DeliveryServiceIntf interface and that will dispatch all the calls on this interface to the RMI service. Below is the pretty self-explanatory client-side code.

public class RmiClientTest {

    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("com/test/rmi/client/rmi-client-context.xml");
        DeliveryServiceIntf deliveryService = (DeliveryServiceIntf) ctx.getBean("deliveryService");
        deliveryService.newDelivery(new Delivery("John Doe", new Date()));
        ...
    }
}

Therefore, the client will not be aware of the fact that the service is running remote and even less about the fact that its method calls are marshaled through RMI. The Spring bean configuration file takes care of these details, so the client code will not be affected if we change the remoting strategy or even if we choose to run the service in-process.

The code for this demo can be found here. The first step is to run ant run-server in order to launch the RMI server and afterwards you need to run ant run-client from another console to start up the RMI client.
Hope this post can give you a basic feeling about Spring’s RMI support. Please feel free to comment on any aspect of this article.

Spring by examples – method interceptors

Spring is a great Java technology that has become a very popular application framework during the past few years. My intention is not to go through the whole concepts and architectural details of the framework, because that kind of information can be easily looked up starting at http://www.springframework.org. As the article title indicates, I intend to provide hands-on examples showing the minimal requirements to bundle certain Spring functionalities in your Java applications. So, because I will not go into the “what’s under the hood” approach unless absolutely necessary, most of the examples might require the knowledge of basic Spring concepts. Anyway, the basic idea is that you must RTFM before deciding if Spring is right for your application.

The first example is a short look at a simple method intercepting strategy. You can read all about this and the whole Spring AOP API here.The source code for this example can be found here. In the project directory run ant compile run to launch the application.

For the beginning let’s consider that we have the service MyService that that has a method doSomething() performing an operation which takes a long time to execute. Below you can see the (pretty dumb) code of this method.

public class MyService {
  public void doSomething() {
    for (int i = 1; i < 10000; i++) {
      System.out.println("i=" + i);
    }
  }
}

In order to print out the performance statistics on the method call, we must first implement the interceptor that actually calculates the execution time for this method. To do this we need to implement the org.aopalliance.intercept.MethodInterceptor interface shipped with Spring. This is actually a callback providing access to the actual call of the methods of our service. The JavaDoc for this interface is here.

public class ServiceMethodInterceptor implements MethodInterceptor {
  public Object invoke(MethodInvocation methodInvocation) throws Throwable {
    long startTime = System.currentTimeMillis();
    Object result = methodInvocation.proceed();
    long duration = System.currentTimeMillis() - startTime;
    Method method = methodInvocation.getMethod();
    String methodName = method.getDeclaringClass().getName() + "." + method.getName();
    System.out.println("Method '" + methodName + "' took " + duration + " milliseconds to run");
    return null;
  }
}

Next we need to proxy our service in order to obtain an instance whose methods are being intercepted by our ServiceMethodInterceptor. To achieve this, all it takes is a little magic in Spring’s bean configuration file, as you can see below.

<beans>
  <bean id="myService" class="com.test.MyService">
  </bean>

  <bean id="interceptor" class="com.test.ServiceMethodInterceptor">
  </bean>

  <bean id="interceptedService" class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="target">
      <ref bean="myService"/>
    </property>
    <property name="interceptorNames">
      <list>
        <value>interceptor</value>
      </list>
    </property>
  </bean>
</beans>

The key in this XML snippet is Spring’s built-in class org.springframework.aop.framework.ProxyFactoryBean which provides the actual proxying of our service. In order to obtain the desired effect we must set the target and interceptorNames properties for this bean. The target property represents the name of the bean that we want to proxy, which in our case is the myService bean. The interceptorNames property holds a list of bean names that will be used as interceptors for the proxied bean. So, yes, you can define more than one interceptor for your bean.
As everything seems to be packed pretty nice, all we need to do now is to have our service instantiated using Spring and call itâs doSomething method.

public class Test {
  public static void main(String[] args) {
    ApplicationContext ctx = new ClassPathXmlApplicationContext("com/test/applicationContext.xml");
    MyService myService = (MyService)ctx.getBean("interceptedService");
    myService.doSomething();
  }
}

So we need to look up the interceptedService bean in order to get the proxied service, but if we choose to remove the performance monitor we can simply lookup the initial myService bean.
Normally, after the method doSomething has run, you should see, as the last output line, something like this:

Method 'com.test.MyService.doSomething' took 281 milliseconds to run

Except from the MethodInterceptor Spring also offers other method interception strategies. For example you can choose to handle a method execution right before or immediately after the actual call, or when an exception is thrown during the execution of your method. The reference documentation about these types of interceptors that Spring offers is available here.

Please note that basic performance monitoring can also be achieved by using Spring’s built-in PerformanceMonitorInterceptor. We used this logic just as a sample for method intercepting, but as your intuition might tell you, this is just one of the many things you can do with this feature of Spring. For example, if you need to implement a fine-grained security module, you might choose not to allow the method call to execute if the user does not have rights on the business method. So, basically, you will have to see for yourself how you can use this functionality in your application.

I hope you find this article useful.
Have a happy coding day :) .