Thursday, December 24, 2009

Referencing Spring beans in Properties collections

It is some times desired to reference Spring beans when injecting properties into some bean. The problem is that the <props> tag doesn’t support references – it supports plain string values only.
While trying to resolve such issue I stumbled onto a discussion in the Spring-Source community forums: http://forum.springsource.org/showthread.php?t=63939.
While adding non-string values into Properties is problematic, adding string values that originate from a bean-value, or a bean’s-property-value, or something similar is a valid usecase. I posted my solution in the thread, but just for your convinience, here goes:
In general, as long as you are using string values, you can can safely replace the <props> tag with <map>:
  <props>
    <prop key="foo">blahhhh</prop>
    <prop key="bar">arrrrgh</prop>
  </props>
Is the same as
  <map>
    <entry key="foo" value="blahhhh"/>
    <entry key="bar">
      <bean class="java.lang.String">
       <constructor-arg value="arrrrgh"/>
      </bean>
    </entry>

    <!-- and you can even do -->
    <entry key="baz" value-ref="someBean"/>
  </map>

Saturday, December 12, 2009

JMS Request-Response with Spring-Integration

A colleague of mine asked me “why would Spring need to write a framework to send / receive JMS messages”.

So here is why:

In short, avoiding frameworks usually leads to breaking the DRY principle. 

In order to send messages you need to
  1. Fetch the connection factory from JNDI.
  2. Create a JMS connection.
  3. Create a JMS session.
  4. Fetch / create the JMS destination.
  5. Create and configure a Producer.
  6. Create your JMS message.
  7. Remember to start() the connection.
  8. Remember to close / cache the JMS resources, and handle errors properly.
In order to receive messages you need to
  1. Fetch the connection factory from JNDI.
  2. Create a JMS connection.
  3. Create a JMS session.
  4. Fetch / create the JMS destination.
  5. Create and configure a consumer - either add a MessageListener, or receive() messages in a loop.
  6. Remember to close / cache the JMS resources, and handle errors properly.
If you’d also like to get a response you need to
  1. Set the message reply to channel. This can be a temp destination, or an existing one. If this is an existing destination, you will also need a message selector and use the JMSCorrelationID.
  2. Create a consumer for the reply message and receive() the message.
  3. On the receiver side you need to create a response message, set the JMSCorrelationID, and send back to the JMSReplyTo destination that was specified on the incoming message.
Writing all this code is naturally prone to errors. Now throw in handling of connections errors (reconnects) as well, and what you get is a whole lot of messy code :P

When using Spring JMS integration framework you can avoid most of the boiler plate code.  When using spring-integration on top of that you can actually decouple your (Java) code from JMS and Spring all together. That is you can avoid having any compile time dependency on JMS or Spring!

The client code:
  <integration:channel id="publishChannel"/>
  <integration:channel id="jmsReplyToChannel"/>
 
  <integration:gateway service-interface="MyPublisher" id="publisher" default-request-channel="publishChannel" default-reply-channel="jmsReplyToChannel"/>

  <jms:outbound-gateway id="jmsOutGateway"
                       request-destination="topic"
                       request-channel="publishChannel"
                       reply-channel="jmsReplyToChannel"
                       connection-factory="jmsConnectionFactory"/>

The publisher is merely an interface :D

public interface MyPublisher {
    public long publish(String msg);
}

The server side code:

<jms:inbound-gateway id="jmsInGateway"
                      request-destination="topic"
                      request-channel="serviceInboundChannel"
                      connection-factory="jmsConnectionFactory"/>
 
  <integration:service-activator input-channel="serviceInboundChannel" ref="myService" method="print"/>

  <integration:channel id="serviceInboundChannel"/>

  <bean id="myService" class="MyServiceImpl"/>

The called service implementation can be anything you like. I only print the message to stdout and return the reception time – this can be later used to test that we are actually performing a synchronised request response style messaging, which is not the case when no JMS response is involved.
public class MyServiceImpl implements MyService {
    public long print(String msg) {
        long now = System.currentTimeMillis();
        System.out.format("%d print: %s\n", now, msg);
        return now;
    }
}

We also need some boring JMS Spring beans definitions to get this working. The code below assumes you have a running ActiveMQ server, but you may replace the provider url to use an embeded ActiveMQ broker (see the commented-out line).
<bean id="jmsJndiTemplate" class="org.springframework.jndi.JndiTemplate">
    <constructor-arg>
      <props>
        <prop key="java.naming.factory.initial">org.apache.activemq.jndi.ActiveMQInitialContextFactory</prop>
        <prop key="java.naming.provider.url">tcp://localhost:61616</prop>
        <!-- prop key="java.naming.provider.url">vm://localhost?broker.persistent=false</prop -->
      </props>
    </constructor-arg>
  </bean>

  <bean id="jmsConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
    <constructor-arg>
      <bean class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiName" value="ConnectionFactory"/>
            <property name="jndiTemplate" ref="jmsJndiTemplate"/>
          </bean>
    </constructor-arg>
    <property name="reconnectOnException" value="true"/>
    <property name="cacheProducers" value="true"/>
  </bean>

  <bean id="topic" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiName" value="dynamicTopics/eran-test"/>
        <property name="jndiTemplate" ref="jmsJndiTemplate"/> 
  </bean>

The diagram below depicts our creation:

Notes:

  • I used a topic here, but it would have been more appropriate to use a queue in most cases…
  • Spring-Integration has it’s own cost. Although the code could be slightly improved performance wise, the internal message format, and the temp queue / channels creation impact performance. So don’t say I didn’t warn you… a plain async message passing style application should probably be written with plain Spring JMSteamplate, and message containers.
  • The code above as is causes Spring to create a lot of temporary resources like queues, consumers, producers, channels. I left it this way for brevity, but most of the temp resources creation can be avoided, thus reducing the load on the message broker.

Friday, December 4, 2009

Value Objects Mapping

My company decided to break its monolithic build and make our life easier.  The main idea was to move from Jini services to Protocol-Buffers over RESTful API.

The main reasons were to introduce loose coupling between our services, adopt open standards, and become cool ;-).

I will probably discuss all this in a later post. The reason I am mentioning all this is that it raised the issue of transforming value objects back and forth.  We are all faced with this issue when developing enterprise software. For example, you create objects in your DAO layer. These are passed to domain objects that massage them a little. Later these objects are passed to your service layer, controller, and presentation layer.

Some of you are probably saying right now, “Are you really coupling all these layers”?  Well, no… Most of us will go and transform the Value Objects (VOs, or DTOs) to another form when passed between the layers. All this copying and transforming is extremely repetitive and time consuming.

When we started working with protobuf, I quickly noticed that transforming protobuf messages into our domain model is going to be an issue. To avoid decoupling between services, each service has to write its own transformation code. This requirement poses a high risk of code duplication (I know some will argue you can’t really call it duplication). My idea was to introduce XML object to object mapping rules.

In comes Dozer. Dozer is a Java Bean to Java Bean mapper that recursively copies data from one object to another. It has many cool features, but lacks the ability to transform your objects into immutable objects – Dozer has no support for constructor arguments. Making your VO classes immutable is desired when you are not administrating them, and when these objects are going to be placed in caches.

Unfortunately, I don’t have a solution to the immutability issue (but more will come - I promise). I have started a private project that will either extend Dozer to support constructor args (hard…), or utilize for its features while extending its abilities to do so (somewhat easier).

I just wonder how many of you stumbled into this…

My Blog

For a long time I've been reading blog post, using tech forums, and open-source framework.

I decided it is time to return the investment.

I intend to post my thoughts, knowledge, and ideas here in this blog.

I'm hoping someone, or the lots of you would find this blog useful.

Enjoy.