» tagged pages
» logout
Spring
Return to Spring

Ben Hale's Blog

(or Cancel)

(Editing anonymously: to be credited for your changes, login or register a new account)

other page actions:

Tags Applied to this Topic

1 person has tagged this page:

Musings from Spring’s front lines

Moving to the Interface21 team blog

As part of an ongoing effort to better brand Interface21 as a company, I’m deprecating my individual company blog and moving to the Interface21 team blog. You’ll find it at http://blog.interface21.com. All of my currently existing posts are there and I’ll be posting from there very shortly.

I realize that this may mean some updates to RSS feeds in the like, but I think it provides a much greater value and simply listening to my ramblings. In addition to me you’ll have the likes of Keith Donald, Colin Sampaleanu, Mark Fisher, and the rest of the Interface21 staff posting and generally improving the community.

Again, sorry for the inconvience, but I’m pretty sure you’ll be happier in the end.

Spring: Ben Hale's Blog

Atlanta DevCon 2006

I just got finished with my Spring 2.0: New and Noteworthy talk at Atlanta DevCon 2006. Let me be the first to say that the conference was great. The site and organizers were all top notch. I’d like to give a special shout-out to Burr Sutter for putting on one heck of a conference. You know that things are going well when the conference center doesn’t have a wireless network but you can get the one from the cafe next door. That’s good karma! The JUG members were all very knowledgeable (even the ones that didn’t know about Spring) and asked great questions. I fielded questions about EJB 3, JPA, ESB, Spring learning curves, Java 5, and Spring Web Flow; every one a great question.

For those of you that weren’t able to make it, I’m posting the slides from that talk in a couple of formats. I’ve decided to post the Keynote file for all you fellow Mac users out there as well as PDFs and the very cool exported HTML that Keynote creates.

Feel free to use the comments to ask me about some of the new and noteworthy features of Spring 2.0.

Spring: Ben Hale's Blog

Message Flow Tracing with AspectJ and JMX

In a project that I used to work on we had a system that would receive messages from a device and make decisions on whether that information would be passed to the user. There were multiple decision levels and one of the problems we always found ourselves asking was if a message was being lost on it’s way through the system.

Before we moved to Spring, it was nearly impossible to tell the answer to that question. Attempts were made to use logging, but the sheer volume of messages that decisions were made on made it tedious at best. Other attempts were made using debuggers but a combination of the volume and the timing changes led to only intermittent success.

Unfortunately I left before we could implement a more suitable solution but if I had, here is what it probably would have been like. At the end I’ll discuss some of the extensions that might be useful in this kind of effort.

To start, we’ve got a set of interfaces and their implementations:

package flowtracingexample;

public interface Component1 {

        void forwardCall();

}

package flowtracingexample;

import java.util.Random;

public class DefaultComponent1 implements Component1 {
       
        private Component2 child;

        private Random r = new Random();
       
        public DefaultComponent1(Component2 child) {
                this.child = child;
        }

        public void forwardCall() {
                if (r.nextBoolean()) {
                        child.forwardCall();
                }
        }

}

package flowtracingexample;

public interface Component2 {

        void forwardCall();

}

package flowtracingexample;

import java.util.Random;

public class DefaultComponent2 implements Component2 {
       
        private Component3 child;

        private Random r = new Random();
       
        public DefaultComponent2(Component3 child) {
                this.child = child;
        }

        public void forwardCall() {
                if (r.nextBoolean()) {
                        child.forwardCall();
                }
        }

}

package flowtracingexample;

public interface Component3 {

        void forwardCall();

}

package flowtracingexample;

public class DefaultComponent3 implements Component3 {

        public void forwardCall() {
        }

}

This is a very simple example, but the gist is that using the fowardCall() method messages are passed 50% of the time to the next child component (ascending numerical order in this case). Note that there is no logic involving tracing in these POJOs.

To implement our tracing behaviors, we’d like to have a set of counters; one for each component. In addition we’d like ways to reset the counters, start and stop monitoring, and determine if monitoring is happening. To do this we implement a class with the counters.

package flowtracingexample;

import org.springframework.jmx.export.annotation.ManagedAttribute;
import org.springframework.jmx.export.annotation.ManagedOperation;
import org.springframework.jmx.export.annotation.ManagedResource;

@ManagedResource
public class FlowTracer {

        private long component1Count = 0;

        private long component2Count = 0;

        private long component3Count = 0;

        private boolean tracing = false;

        @ManagedAttribute
        public long getComponent1Count() {
                return this.component1Count;
        }

        @ManagedAttribute
        public long getComponent2Count() {
                return this.component2Count;
        }

        @ManagedAttribute
        public long getComponent3Count() {
                return this.component3Count;
        }

        @ManagedAttribute
        public boolean getTracing() {
                return this.tracing;
        }

        public void incrementComponent1Count() {
                if (this.tracing) {
                        component1Count++;
                }
        }

        public void incrementComponent2Count() {
                if (this.tracing) {
                        component2Count++;
                }
        }

        public void incrementComponent3Count() {
                if (tracing) {
                        component3Count++;
                }
        }

        @ManagedOperation
        public void resetAllComponentCount() {
                resetComponent1Count();
                resetComponent2Count();
                resetComponent3Count();
        }

        @ManagedOperation
        public void resetComponent1Count() {
                this.component1Count = 0;
        }

        @ManagedOperation
        public void resetComponent2Count() {
                this.component2Count = 0;
        }

        @ManagedOperation
        public void resetComponent3Count() {
                this.component3Count = 0;
        }

        @ManagedOperation
        public void startTracing() {
                tracing = true;
        }

        @ManagedOperation
        public void stopTracing() {
                tracing = false;
        }
}

The methods and their contents are pretty straight forward for this class. What may be new to you are the annotations on this class. These annotations are used by Spring’s JMX support to automatically build up MBean management interfaces when each bean is deployed to the JMX MBeanServer.

  • ManagedResource: Declares that this class should be exposed as a JMX MBean
  • ManagedAttribute: Declares that the JavaBean property represented by this getter/setter should be a MBean attribute. You need to annotate both the getter and setter if you want read and write access to this attribute.
  • ManagedOperation: Declares that this method should be exposed as an MBean operation

Finally it’s a matter of wiring the whole thing together. First, we wire together the components that make up the flow. Next we declare the aspects that will put the tracer on each of the components. In this case we are using the very sweet AspectJ pointcut language. Finally we setup the JMX exporter to autodetect instances of classes that have the @ManagedResource annotation on them.

<?xml version=“1.0″ encoding=“UTF-8″?>
<beans xmlns=“http://www.springframework.org/schema/beans”
        xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”
        xmlns:aop=“http://www.springframework.org/schema/aop”
        xsi:schemaLocation=“http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd”
>

        <!– Components –>
        <bean id=“component3″ class=“flowtracingexample.DefaultComponent3″ />

        <bean id=“component2″
                class=“flowtracingexample.DefaultComponent2″>

                <constructor-arg ref=“component3″ />
        </bean>

        <bean id=“component1″
                class=“flowtracingexample.DefaultComponent1″>

                <constructor-arg ref=“component2″ />
        </bean>

        <!– Aspect –>
        <bean id=“flowTracer” class=“flowtracingexample.FlowTracer” />

        <aop:config>
                <aop:aspect id=“component1Aspect” ref=“flowTracer”>
                        <aop:before method=“incrementComponent1Count”
                                pointcut=“execution(public void flowtracingexample.Component1.forwardCall())” />

                </aop:aspect>

                <aop:aspect id=“component2Aspect” ref=“flowTracer”>
                        <aop:before method=“incrementComponent2Count”
                                pointcut=“execution(public void flowtracingexample.Component2.forwardCall())” />

                </aop:aspect>

                <aop:aspect id=“component3Aspect” ref=“flowTracer”>
                        <aop:before method=“incrementComponent3Count”
                                pointcut=“execution(public void flowtracingexample.Component3.forwardCall())” />

                </aop:aspect>
        </aop:config>

        <!– JMX –>
        <bean class=“org.springframework.jmx.export.MBeanExporter”>
                <property name=“autodetectModeName” value=“AUTODETECT_ALL” />
                <property name=“assembler”>
                        <bean
                                class=“org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler”>

                                <property name=“attributeSource”>
                                        <bean
                                                class=“org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource” />

                                </property>
                        </bean>
                </property>
                <property name=“namingStrategy”>
                        <bean
                                class=“org.springframework.jmx.export.naming.IdentityNamingStrategy” />

                </property>
        </bean>

</beans>

The next things that we need to do is have a driver class. In this case the driver class just sends a message at some random delay under 750ms.

package flowtracingexample;

import java.io.IOException;
import java.util.Random;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class FlowTracingExample {

        public static void main(String[] args) throws InterruptedException,
                        IOException {
                ApplicationContext ctx = new ClassPathXmlApplicationContext(
                                “classpath:flowtracingexample/applicationContext.xml”);

                Component1 comp = (Component1) ctx.getBean(“component1″);
                Random r = new Random();

                System.out.print(“Ready…”);
                 System.in.read();

                for (;;) {
                        comp.forwardCall();
                        Thread.sleep(r.nextInt(750));
                }
        }
}

In my case, I’m going to run this application with the Java VM Management running since it gives me a free MBean server (and I like the pretty memory graphs). If you haven’t heard of this, it’s a system property in Java 5 VMs that causes the VM to use JMX to manage itself. It has beans for memory consumption, threading, and a million other things. You start it simply by putting -Dcom.sun.management.jmxremote on the command line of your running application. In another nifty Java 5 addition, I’m going to use jconsole to display my results.

Based on my rusty math skills, over the long term, I’d expect to see Component 1 called 100%, Component 2 called 50%, and Component 3 called 25% of the time. Lets see:

Tracing Screen Shot

It’s good to see that I remember my probabilities right. The best part is this still meets good design principals. For example, none of the components know anything about the tracing because that’s not what they do. As well, all of the tracing requirements for this subsystem are contained in one class and have one implementation meeting the 1:1 requirements to implementation goal of AOP. Finally, with the ability to turn off the tracing, any performance impact is more or less neutralized. I know, I know incrementing an integer isn’t that expensive, but if you’re tracing did something expensive, it’s nice to have and you don’t have to worry if you want to send it into production; you can simply disable the monitoring until your customer calls in for support.

So the graphs sure are pretty and maybe even tell you stuff if you know your expected percentages, but what else could you do? How about the last 100 messages to go by and their decisions? How about a log of the reason that a message was dropped? How about correlation between drop decisions and the absence of a message at the end of the pipe? Wouldn’t it be nice to know that a message had been lost (perhaps due to a threading issue) because you never intentionally dropped it but it didn’t make it to the end within 500ms of its entry? Along that same line, how about an email to the admin if the time it takes to get from one end of the pipe to the other gets over 250ms?

The tracing/monitoring possibilities are endless (and pluggable!). What will you do with it?

And of course, the source code.

Spring: Ben Hale's Blog

Another Reason to Love Spring 2.0: Interceptor Combining

Recently I was working on a project that had a Swing client communicating via RMI to a service layer. The service layer was marked with transactions and everything seemed to work fine. However everytime we’d get an exception at the Hibernate DAO layer, Spring would turn the exception into a runtime exception and it would get propagated all the way up the stack and across the RMI connection as a RemoteException. Whenever the exception was deserialized there would be an exception on the client (separate from the RemoteException.The decision was taken to simply introduce an aspect. Any exception that subclassed ServiceAccessException would be let through to the client while anything else would be converted to a FilteredServiceAccessException (a subclass of ServiceAccessException) and then be thrown. This led to some loss in content, so we made sure to log the original exception on the server where it could be useful and let the client show a generic dialog so the user knew generally what had happened.

Now this was a pretty good plan and seemed on track to work until we tried to implement it. We were using the magic way of autoproxying any bean that had @Transactional on it to get our transactional proxies. We could have updated the definition of that autoproxying to make sure that the advice for this exception filtering was added (think setPreInterceptor in TransactionProxyFactoryBean) but the the autoproxying was catching more than just the service layer.

So where did that leave us? We could either A) explicitly declare each use of the TransactionProxyFactoryBean, B) make two different sets of autoproxying and have them be mutually exclusive for one another, or C) ignore the requirement for now and hope something magical happens. Since the product was still six months away from consumers and I try to follow the principal of the ‘last responsible moment‘ introduced to me by Jeremy Miller I decided to table the issue with choice A being my backup plan (better to have no magic than twice as much magic).

Lo and behold, Spring 2.0 solved my problem. I cannot for the life of me find where I read it, but starting in one of the milestones of 2.0, when a bean is proxied the proxy factory can now detect that the bean already has a proxy and just add the intended interceptor as another interceptor (if you know where it was leave the link in the comments please). This means that I could just use the new magic (<tx:annotation-driven>) and simply add an aspect with the proper pointcut that I wanted and I wouldn’t have to worry about the transaction proxy and the AOP proxy getting crossed up. Not quite sure what this is all about? How about an example. First an interface and implementation.

package interceptorcombiningexample;

import org.springframework.transaction.annotation.Transactional;

@Transactional
public interface ExampleTarget {

        void exampleMethod();

}

package interceptorcombiningexample;

public class DefaultExampleTarget implements ExampleTarget {

        public void exampleMethod() {
        }
}

Notice that the interface is marked @Transactional. We’ll use that to get some magic autoproxying later on. Next we’ll take a look at the bean definitions.

<?xml version=“1.0″ encoding=“UTF-8″?>
<beans xmlns=“http://www.springframework.org/schema/beans”
        xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”
        xmlns:aop=“http://www.springframework.org/schema/aop”
        xmlns:tx=“http://www.springframework.org/schema/tx”
        xsi:schemaLocation=“http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd”
>

        <tx:annotation-driven />

        <aop:config>
                <aop:aspect id=“exampleAspect” ref=“exampleAdvice”>
                        <aop:before method=“exampleAdvice”
                                pointcut=“execution(* interceptorcombiningexample.ExampleTarget.exampleMethod())” />

                </aop:aspect>
        </aop:config>

        <bean id=“exampleAdvice”
                class=“interceptorcombiningexample.ExampleAdvice” />

        <bean id=“exampleTarget”
                class=“interceptorcombiningexample.DefaultExampleTarget” />

        <bean id=“transactionManager”
                class=“interceptorcombiningexample.DummyTransactionManager” />

</beans>

You’ll notice that we set up annotation driven transactions which will automatically build a proxy around our DefaultExampleTarget. In addition, we define another aspect that should need to proxy the same DefaultExampleTarget bean. Finally lets take a look at our executable class.

package interceptorcombiningexample;

import org.springframework.aop.Advisor;
import org.springframework.aop.framework.Advised;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class InterceptorCombiningExample {

        public static void main(String[] args) {
                ApplicationContext ctx = new ClassPathXmlApplicationContext(
                                “classpath:interceptorcombiningexample/applicationContext.xml”);

                ExampleTarget target = (ExampleTarget) ctx.getBean(“exampleTarget”);
                if (target instanceof Advised) {
                        Advised advised = (Advised) target;
                        System.out
                                        .println(“Advisor count: “ + advised.getAdvisors().length);
                        for (Advisor advisor : advised.getAdvisors()) {
                                System.out.println(“Advisor type: “
                                                + advisor.getAdvice().getClass().getName());
                        }
                }
        }

}

This class takes advantage of a nice little feature of Spring’s proxy mechanism. Any Spring created proxy can be cast to the Advised interface. This interface will give you access to all of the interceptors in a proxy. When we go ahead and run this class the output shows:

Advisor count: 3
Advisor type: org.springframework.aop.interceptor.ExposeInvocationInterceptor
Advisor type: org.springframework.transaction.interceptor.TransactionInterceptor
Advisor type: org.springframework.aop.aspectj.AspectJMethodBeforeAdvice

From this we can see that not only was the TransactionInterceptor contained in the proxy, but also the AspectJMethodBeforeAdvice.

It’s important to know that this shouldn’t affect any implementations that already exist that attempt to do the same thing. This should just make life easier for all those who’ve been waiting for the ‘last responsible moment’ to solve this problem. )

P.S. As in the last post, I’ve included an archive of the project from this example so that you can see the rest of the code if you need it.

Spring: Ben Hale's Blog

Spring 2.0’s JMS Improvements

With the release of Spring 1.1 the Spring community was given it’s first taste of JMS support. This support included exception translation, message conversion, and a template class much like JdbcTemplate. This support also took care of domain unification between the JMS 1.0.2 and 1.1 specs. The centerpieces of this support are the JmsTemplate class and it’s JMS 1.0.2 counterpart JmsTemplate102.

This support was a great improvement over using the raw JMS APIs to do enterprise messaging. However it did have a shortcoming; the JmsTemplate only supported synchronous reception of messages using the JmsTemplate.receive() methods. This behavior worked well for many people but the vast majority of users of ended up rolling their own implementations of an asynchronous consumer. In short, they wanted what EJB 2 called Message Driven Beans.

But no longer will users do without. With the release of 2.0M1 and the final 2.0 release later, native support for asynchronous reception of JMS messages has been added. The JmsTemplate is still used for sending of messages at his always been, but it has now been joined by subclasses of AbstractMessageListenerContainer such as DefaultMessageListenerContainer, SimpleMessageListenerContainer, and ServerSessionMessageListener.

Let’s take a look at how to use these MessageListenerContainers. The first step is to create a class that can receive the messages. To do this, one must create a class that implements the MessageListener interface.

package jmsexample;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

public class ExampleListener implements MessageListener {

        public void onMessage(Message message) {
                if (message instanceof TextMessage) {
                        try {
                                System.out.println(((TextMessage)message).getText());
                        } catch (JMSException e) {
                                throw new RuntimeException(e);
                        }
                } else {
                        throw new IllegalArgumentException(
                                        “Message must be of type TestMessage”);
                }
        }

}

Once you have that, you’ll need a message producer. This code is the same as it was back before Spring 2.0, so if you have code that does this already, it should not require any changes.

package jmsexample;

import org.springframework.jms.core.JmsTemplate;

public class ExampleProducer {

        private JmsTemplate jmsTemplate;

        public ExampleProducer(JmsTemplate jmsTemplate) {
                this.jmsTemplate = jmsTemplate;
        }

        public void sendMessage() {
                jmsTemplate.convertAndSend(“Example Message”);
        }

}

Next, you need to configure your context to create a MessageListenerContainer that routes messages to this bean. You’ll notice that I’m using ActiveMQ implementation classes in this example. This just happens to be one of many JMS implementations and happens to be the one that I’m most familiar with.

<?xml version=“1.0″ encoding=“UTF-8″?>
<beans xmlns=“http://www.springframework.org/schema/beans”
        xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”
        xsi:schemaLocation=“http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd”
>

        <bean id=“messageListener” class=“jmsexample.ExampleListener” />

        <bean id=“messageProducer” class=“jmsexample.ExampleProducer”>
                <constructor-arg ref=“jmsTemplate” />
        </bean>

        <bean id=“jmsTemplate”
                class=“org.springframework.jms.core.JmsTemplate”>

                <property name=“connectionFactory” ref=“connectionFactory” />
                <property name=“defaultDestination” ref=“destination” />
        </bean>

        <bean id=“destination” class=“org.activemq.message.ActiveMQQueue”>
                <constructor-arg value=“jmsExample” />
        </bean>

        <bean id=“listenerContainer”
                class=“org.springframework.jms.listener.DefaultMessageListenerContainer”>

                <property name=“connectionFactory” ref=“connectionFactory” />
                <property name=“destination” ref=“destination” />
                <property name=“messageListener” ref=“messageListener” />
        </bean>

        <bean id=“connectionFactory”
                class=“org.activemq.ActiveMQConnectionFactory”>

                <property name=“brokerURL” value=“tcp://localhost:61616″ />
        </bean>

</beans>

I’m going to skip it for now, but obviously you’ll need to have an MQ started, and a main method that bootstraps your context. I’ve added an archive of the project from this example so that you can see the rest of the code if you need it.

Finally, you just need to run your application and take a look at the output.

Example Message

One thing to note is that so far we’ve been dealing with asynchronous reception with a single consumer thread. It is possible to multithread to your consumers (remember that you’ll still have to make them stateless or thread-safe) using the concurrent consumers property of the MessageListenerContainer.

<bean id=“listenerContainer”
        class=“org.springframework.jms.listener.DefaultMessageListenerContainer”>

        <property name=“concurrentConsumers” value=“5″ />
        <property name=“connectionFactory” ref=“connectionFactory” />
        <property name=“destination” ref=“destination” />
        <property name=“messageListener” ref=“messageListener” />
</bean>

One thing I’d like to note (from my own painful experience) is to make sure that you don’t use concurrent consumers with a Topic. Remember that in a JMS topic all messages are delivered to all consumers on a topic. This means that if you have concurrent consumers on a topic, all of them will receive the same message; typically something that you’d want to avoid. However, if you’re using a queue, obviously this would dispatch each new message to the consumers in a round-robin fashion.

So, there you have it. It isn’t very flashy and is probably very similar to something you may have written at some point, but now all you have to do is use it, you don’t have to maintain it. Let me also say that this is just the tip of the iceberg. The MessageListenerContainers have the ability to take part in transactions, use custom threadpools (like the ones provided with an app server) with the new Spring TaskExecutorabstraction, and even expose the native JMS session to the consumer. Each of those things is a topic for another post though.

Spring: Ben Hale's Blog

Hello World!

It seemed fitting that my first post be titled ‘Hello World!’ In addition to following a strong programming tradition, it certainly describes my future. I’ve recently joined the Interface21 family and there’s lots of travel on tap.

I’ve been programming in Java for about 8 years now but am a recent convert to Spring. In fact, you might consider me the model convert. In the beginning of my carreer I spent quite a bit of time working in a JSE environment and dismissing Spring as a tool to help build webapps in JEE. But one fateful trip to Scandanavia and quite a few hours with Keith Donald and my whole outlook changed. A quick conversion of my project to a spring based solution opened me up to a whole world of quick, focused, high-quality development. To skip the end, I liked Spring so much I ended up joining the company.

In the formative years of my career I did quite a bit of work in network management. This domain exposed me to all sorts of interesting bits of enterprise software so you can expect me to focus quite a bit of effort in that area for the near term.

Spring: Ben Hale's Blog

Username:
Password:
(or Cancel)