Spring Integration 2.0.0.RC2 is out and I really wanted to upgrade in my current project. Few of the reasons to upgrade were the dependency of Spring 3 and the support for JMX. Because SpringSource changed a few things in the 2.0.0 release, I want to share the steps I had to take and issues that I solve to migrate from Spring Integration 1.0.3 to the latest version 2.0.0.
The first thing to do is, how surprising, upgrading your dependency. I use Maven so for me it is as simple as changing the version to 2.0.0.RC2.
<dependency> <groupid>org.springframework.integration</groupid> <artifactid>spring-integration-XXXX</artifactid> <version>2.0.0.RC2</version> </dependency>
Package structure changes
One of the first things that you will notice is that your Spring Integration project does not compile anymore , because they have moved some classes. All classes from the org.springframework.integration.core package have moved to org.springframework.integration. This package contains the now the often used classes like Message.java and MessageChannel.java.
Another class that I use quite often is the MessageBuilder.java. This class moved from the message to the support package. The message package now only holds two messages classes, ErrorMessage.java and GenericMessage.java.
I can see you thinking.. where is the StringMessage.java class gone to? Well, they have removed it.
Removed classes and methods
I have used the StringMessage class a few times in my project, but couldn’t find it anymore after the upgrade. So I looked in Jira and found this issue. StringMessage is gone, but you can easily refactor your code to one of the following options:Message<String> stringMessage1 = new GenericMessage<String>("one"); Message<String> stringMessage2 = MessageBuilder.withPayload("two").build();
In one of my routers called the method MessageChannel.getName() to route the message to the correct message channel. Unfortunately for me, they removed the method from the interface. To solve this problem I send the message directly to the channel instead of returning the name of the channel.
When you use the QueueChannel.getMessageCount() method, you will notice that it is no longer there. Well it is, but under a different name. You can use the getQueueSize() method instead, which is just a renamed method with the same implementation.
In my project I use a poller for retrieving messages. In Spring Integration 1.0.3 you would configure a poller like this:<si:poller max-messages-per-poll="1"> <si:interval-trigger time-unit="SECONDS" interval="90"/> </si:poller>
As you can see, you could specify a time unit. In SI 2.0.0.RC2 this is changed in the following code:<si:poller max-messages-per-poll="1" fixed-delay="90000"/>
In the new version of the poller, the interval-trigger and cron-trigger have been deprecated. They will be removed in 2.1. The ‘fixed-delay‘, ‘fixed-rate‘, ‘cron‘, or ‘trigger‘ attributes should now be used instead. With the new attributes also comes the removal of the time-unit of the attribute. The default time-unit is now milliseconds, so don’t forget to update your properties.
Try a Milestone release!
Before we upgraded to the latest version of Spring Integration we already tried to upgrade with a milestone release (2.0.0.M7). The fun thing about trying a milestone release is that you prepare yourself for the changes and get a good indication about the amount of work that the upgrade requires.
Another cool thing is that you can help the community to check for bugs or suggest an improvement. During our milestone upgrade my colleague Jettro Coenradie and I found a bug in the splitter element. So we reported it and now it is fixed in the current release and made the software world a little better .
Full Migration Guide
SpringSource will probably publish a full migration guide by the time version 2.0.0 is finished. In the meantime I hope that my post was any helpful during your own migration.
Thanks for this post! We will be providing a migration guide as you mentioned, and we will include a bit more rationale behind some of the changes. I do want to mention here that every one of these changes was a result of much discussion and debate where we found a strong enough reason in the end (often having to do with dependency structures, etc. since we have a self-enforced rule of preventing any cycles between packages, and we try to maintain 0% excessive structural complexity).
I also want to point out that any router can return MessageChannel instances (or just channel names), so there should not have been any reason to call getName() for the router return values. As for the rationale for removing that method from the interface, we have anonymous channels in a few cases, so that method seemed a bit too demanding to be on the main interface (I’m not a fan of “optional” methods on interfaces). Also, we added a NamedComponent interface that plays a more general role in the framework now (e.g. for MessageHistory), and we wanted to make sure to enforce consistency in its use.
[…] a "migration guide" within the next couple weeks. Please stay tuned, but in the meantime this blog by Roberto van der Linden of JTeam covers most of the main […]