Home

News: Asynchronous Messaging Made Easy With Spring JMS

  1. In "Asynchronous Messaging Made Easy With Spring JMS," hosted by ONJava, Srini Penchikala shows a traditional JMS application along with implementing the same application with Spring to show a comparison between the two, leveraging Spring's capabilities in resource management in a messaging environment.

    Most of the code is delivered in downloads, but the article shows how traditional JNDI usage and Spring differ, cutting much boilerplate code for acquiring Queues and Connections out.

    Open source tools such as Hermes and JBoss MQ are used throughout as well, showing how the toolset enables rapid development and debugging.

    Threaded Messages (28)

  2. What a waste of time, both the author's and mine. So you have moved the JMS configuration/lookup from Java code to XML. OK, Spring JMS is useful if you need the full JMS functionality in your application (so we let the spring guys create the abstraction layer for us); but if you don't, it is much easier to create a wrapper around a subset of JMS that you need.
  3. XML is not required[ Go to top ]

    In usual Spring fashion, the example is written using Spring XML. But the JmsTemplate is very useful even without using XML. There is nothing to stop you from instantiating these objects with new and looking up the ConnectionFactory using standard JNDI mechanisms.That is where Spring convenience classes (ie. for JDBC, JMS, JNDI, et. al.) really shine. They are often very useful without the Spring core container.It would be nice for articles that use Spring convenience classes to stick to just the convenience part, and leave the rest of the Spring container out of it. People see <bean id="..."> and freak out.
  4. XML is not required[ Go to top ]

    I should have been more precise, I do know that Spring's XML config is only an option and not a necessity. But if the article's purpose is to show how simple Spring JMS is compared to the standard JMS it should compare java code with java code. And not some XML (tucked away two pages earlier) + Java and Java.

    BTW, I have used Spring and still use it. And I do not hate XML, just the way it is often misused. The only things I configure in Spring via XML are the classes that can be replaced with their Testing (mock) components, and classes that a user administrator might have to change. Everything else belongs in the code.
  5. What a waste of time, both the author's and mine. So you have moved the JMS configuration/lookup from Java code to XML.

    I'm so happy there are reasonable people like Petar still around here. In visiting java.net I'm stunned to see poeple still excited about EJB 3 and Sun's app server. On the other hand, back at TSS it's the never ending make J2EE easier with more XML to learn, more software layers, it's just nutty. JMS was never particularly difficult. If it is then we need to lobby to make JMS easier, not more Spring, which is becomming just as bad as J2EE in terms on constant bloat.
    Taylor
  6. Spring makes it little easier[ Go to top ]

    I have been working on J2EE projects for a while, but i would have to admit that Spring does ease development to an extent. Its not that JMS is difficult to write but i personally feel that externalizing most of the configuration and preparation of JMS objects, in fact any J2EE objects in general is pretty good thing, since it alleviates developers from all that mundane tasks. Spring is not only the framework that allows us to do this, we got HiveMind and Pico as well.
    Another issue is the constant abuse of the word container. J2EE container has far more responsibilities than what Spring or HiveMind or any other framework has to offer.
    I do agree that we are haunted by more and more XML configurations but i think Tiger probably would take away most of the pain through annotations.
    I personally found that Spring framework was very useful in weaving objects together. In fact, our domain [conceptual] model was used to weave all of our objects.
    Anyway, i like the article because we did use Spring in configuring JMS and it was lot easier for us to move between different environments [development/test/production/demo] etc
  7. Spring makes it little easier[ Go to top ]

    I do agree that we are haunted by more and more XML configurations but i think Tiger probably would take away most of the pain through annotations.

    So you have to recompile the source if you need
    to change configuration.
    Great !!
    Think about a concrete case where you sell your fantastic
    service with the configuration in the annotations and
    the poor user wants to change something.
    Really a great idea to make money, indeed.

    Guido.
  8. Spring makes it little easier[ Go to top ]

    Went through the article, showed how to use Spring for sending JMS message to a queue. I believe this was already available in previous versions of Spring. I was hoping to find an example for 'asynchronous' receive in the new version being described by the article. Did I miss it?
  9. Spring makes it little easier[ Go to top ]

    I do agree that we are haunted by more and more XML configurations but i think Tiger probably would take away most of the pain through annotations.
    So you have to recompile the source if you needto change configuration.Great !!Think about a concrete case where you sell your fantasticservice with the configuration in the annotations andthe poor user wants to change something.Really a great idea to make money, indeed.Guido.

    No not really - not if annotations are done correctly. Annotations should be broad concepts not configuration-specific.

    For example if I mark a method as
    @Remote or @RequiresTransaction

    I shouldn't have to
      1) Configure it with XML - if my framework can read annotations
      2) Recompile it - since annotations can be ignored if not needed or used with different frameworks.

    This assumes (gulp!) that two separate frameworks can be told to recognize the same annotation.

    Note that marking a method as a possible remoted method or one that requires a transaction is something that should be known at development time.
  10. Spring makes it little easier[ Go to top ]

    No not really - not if annotations are done correctly. Annotations should be broad concepts not configuration-specific.For example if I mark a method as@Remote or @RequiresTransactionI shouldn't have to &nbsp;&nbsp;1) Configure it with XML - if my framework can read annotations&nbsp;&nbsp;2) Recompile it - since annotations can be ignored if not needed or used with different frameworks. This assumes (gulp!) that two separate frameworks can be told to recognize the same annotation.Note that marking a method as a possible remoted method or one that requires a transaction is something that should be known at development time.
    Well, configuration is, I would say by definition, something
    that makes the SW adapt to runtime environment without changes: the endpoint of a web service, the table for a
    class OR mapping, the JMS provider.
    So, putting configuration elements in the source code is
    a nonsense.
    You say "...if annotations are done correctly. Annotations should be broad concepts not configuration-specific".
    Right, unfortunately latest silver bullets, JAXWS and
    EJB3/JPA, show something different.
    Correct me if I am wrong, annotations creators are deeply
    involved in those specs.
    A form of stockholm syndrome ?

    Guido.
  11. If it was such a waste of your time, I am not sure why you had to comment on it.....
  12. Some statistics for code in the article (after a more sensible layout and deletion of blank lines):

    traditional approach: 48 lines of Java (22 statements)
    Spring: 11 lines of Java (7 statements), 55 lines of XML (30 elements)

    Why do Spring people hate Java so much?
  13. Why do Spring people hate Java so much?

    Configuration moved to XML means less opportunities for developer to make assumptions about deployment environment. You are not forced to recompile the code in case you need to change something. Simple text editor and good documentation is good enough to maintain the system.

    It's a Good Thing (tm), especially if you have separate development and deployment/maintenance teams, which is common for the big companies.
  14. More importantly, it's a good thing when moving between environments, such as development, QA, and production. WHile not everyone has the separate deployment teams that Sun envisioned when writing up the original J2EE specs, most everyone has an environment with test and production servers separate. There's a lot of deployment-specifics that just don't belong in code, and while J2EE provides some mechanism for dealing with this, it's very vendor-specific in reality and is also quite difficult to deal with. I'll take a little extra XML config anyday if I get vendor portability and easy switching between deployment environments.
  15. traditional approach: 48 lines of Java (22 statements). Spring: 11 lines of Java (7 statements), 55 lines of XML (30 elements). Why do Spring people hate Java so much?

    Food for thought: Consider a traditional plain JDBC-based DAO layer versus a typical modern ORM-based DAO layer - for example: classic Hibernate or TopLink, or a SQL-mapping-based approach like iBATIS SQL Maps.

    In the JDBC-based layer, you'll have -say- 20000 lines of Java code and virtually no XML. In the ORM-based layer, you'll probably have a few 1000 lines of XML mapping code plus maybe a few 1000 lines of Java data access code.

    So according to the Java/XML line comparison logic above: Why do Object/Relational Mapping people hate Java so much?

    Juergen
  16. I am not sure the comparison is relevant. When you implement a database access with an ORM, the XML files are used each time there is an access to the database. No more cut/paste of the fields, no more : The factorization is important.
    When you use Spring to do some jms, you do not have the same factorization. In fact it is more or less a replacement. So it's just a question of choice, between spring (+unchecked exceptions+xml+templates etc.) and handmade (+checked exceptions+noxml+centralize code in java files etc.)
    for instance, in my last project, i choosed to use spring to encapsulate ejb accesses but handmade messaging.
  17. I am not sure the comparison is relevant. When you implement a database access with an ORM, the XML files are used each time there is an access to the database. No more cut/paste of the fields, no more : The factorization is important.When you use Spring to do some jms, you do not have the same factorization. In fact it is more or less a replacement. So it's just a question of choice, between spring (+unchecked exceptions+xml+templates etc.) and handmade (+checked exceptions+noxml+centralize code in java files etc.)

    I agree that O/R Mapping is a particular strong case for separation of mapping information, and is pretty unique in that some degree. The argument does show nicely that a plain comparison of Java versus XML lines of code -- as posted above -- is pointless, though.

    That said, a basic similarity in terms of factoring out structural, environment-specific information does apply: With Spring's JMS support, the only information that actually resides in bean definitions (typically in the context of XML configuration files) is environment-specific configuration such as concrete JNDI names. There's quite a bit of that in typical JMS usages, for example all ConnectionFactory and Queue/Topic references used.

    Everything else, in particular the actual JMS handling, typically resides in Java code even in a Spring-based application. In the case of JMS, it does not matter to Spring's bean container what the application component actually does with the ConnectionFactory/Queue/etc references. It can use raw JMS to work with them just as it can use Spring's JmsTemplate to work with them.

    So in essence, there's actually two separate feature levels offered here:

    * Use Spring's general bean container and JNDI support to factor out JNDI lookup information and pass ConnectionFactory/Queue/etc as bean references into application components. This is the typically perceived XML configuration part, which is actually completely generic: It just deals with generic JNDI lookups and injection of bean references, not having particular JMS specifics.

    * As a separate decision: Use Spring's JmsTemplate to implement the application components that need to perform JMS operations. This will operate on the given ConnectionFactory/Queue/etc, offering unchecked exceptions in combination with callback-style JMS handling. JmsTemplate can either be used as programmatic helper (instantiated directly) or passed in as bean reference itself. This is completely up to the application developer.

    Note that all of the above is directly equivalent to Spring's JDBC support, Hibernate support, etc: It's always about the two separate feature levels of *externalized configuration* on the one hand and *programmatic implementation helpers* on the other hand. Those are always separate decisions; they just happen to work together nicely when combined.

    Juergen
  18. Use Spring's general bean container and JNDI support to factor out JNDI lookup information and pass ConnectionFactory/Queue/etc as bean references into application components. This is the typically perceived XML configuration part, which is actually completely generic: It just deals with generic JNDI lookups and injection of bean references, not having particular JMS specifics.
    .Juergen
    That's the choice I had made. In fact I am not specially confortable with the Spring templates as it pushes you to use yet another a specific feature of a framework to solve a common (and here, rather simple) problem. I mean, may be I could save some lines by using jdbcTemplate or JmsTemplate but I should have to learn yet another specific feature instead of using the canonical code. And maybe I just re-invented the wheel (my sender also has a timeOut, ConnectionFactory, etc), but I did not have to learn the way Spring re-interpreted the wheel. And my code is not bounded to that part of Spring (I mean... not yet!)
    (I wish I could have used annotations instead of xml, anyway)
    btw: jms rocks! And Spring? Spring is good for you. I mean it. The discovery of Spring (+hibernate), and the reading of Spring code, was a haha experience for me.
  19. Missing the point?[ Go to top ]

    Gabriel, if you'd rather spend your time reinventing system-level wheels why not just give up application programming and start writing your own operating system? In my opinion, Spring's JMS implementation is a welcome abstraction that adds another arrow to an already very useful quiver. The main benefits in my opinion are:

    1. app server Portability. A spring project can be dropped into virtually any application server by merely dropping in a .war file. No sticky app-server JNDI configuration required. Just deploy and run.

    2. code portability. Have we also forgotten how nice it is to be able to load an entire spring project outside of an app server? Two incredibly useful examples would be unit testing and alternative front-end's to an application (i.e. SWING or your GUI library of choice). Using the exact same Model and Controller classes with a gui front end is a breeze in Spring. NO changes necessary.

    And what computer scientist worth his weight in beans has a difficult time learning a simple XML schema like <bean id="myBean" class="the.class.that.is.my.bean">?

    Spring is an extremely handy tool, and the addition of asynch JMS just gives it even more remoting strength. Thank you TSS for letting us know about the new feature.
  20. Change the title[ Go to top ]

    Probably this article needs a title change to
    +++ How to use Spring JMS +++
    There is nothing special in Spring JMS except the externalization/associate objects dependency injection.

    Please stop from publishing these kinds of articles.
  21. I found it useful ...[ Go to top ]

    Please stop from publishing these kinds of articles.

    These comments don't add any value. The articles may not be everyone's cup of tea, but they are still informative and promote discussion on alternatives - as has been the case for this article. It's quite easy to skim an article that you don't find relevant, but others find the discussion quite useful to read.
  22. I really love it when people show how "hardcore" they are by spitting on everything related to {insert popular whipping boy here}.

    I don't find that JMS is "already easy enough". Dependencies on JNDI, MDBs, etc., make it a pain to use in a lot of cases. Spring JMS, from what I can tell, brings the following to the table:
    1. A more sane, unchecked exception hierarchy (same as Spring data access does).
    2. Code transparency between 1.0 and 1.1 APIs
    3. Abstraction of connection, so JNDI-specifics don't have to reside in your code (which is not where they belong).
    4. Vendor portability, because connections are handled in a consistent, abstracted way.

    Abstraction layers like this aren't always necessary, but when they provide utility, they should be recognized and not assaulted because they don't provide that utility in your specific situation.

    The holy grail for this to me would be the ability to have JMS listeners, like MDBs, but without dealing with EJBs at all. That way, you could deploy listeners in something like Tomcat with relative ease, or (another example of vendor portability), not have to worry about whether your app is running in Tomcat, Oracle, BEA, etc. That's not a need for all applications, but when it is necessary, it's very helpful for these kinds of abstractions.
  23. The holy grail for this to me would be the ability to have JMS listeners, like MDBs, but without dealing with EJBs at all. That way, you could deploy listeners in something like Tomcat with relative ease, or (another example of vendor portability), not have to worry about whether your app is running in Tomcat, Oracle, BEA, etc.

    Drew, are you aware of the JMS listener support in Spring 2.0? This should be pretty close to your holy grail :-)

    http://static.springframework.org/spring/docs/2.0-m2/api/org/springframework/jms/listener/package-summary.html

    Granted, it's not extensively documented yet... This is effectively a full-fledged asynchronous JMS listener container with full portability across JMS providers. There's a couple of container variants with different tradeoffs. DefaultMessageListenerContainer covers the typical scenarios, even - optionally - XA message reception!

    There's also the Jencks project (http://www.jencks.org), which essentially takes a different approach towards the same problem, and mainly targets non-J2EE environments. It's based on JCA 1.5 and JTA - in constrast to Spring 2.0's own support which is based on the plain JMS API (1.0.2 or 1.1), with optional use of JTA for XA message reception.

    Juergen
  24. I have taken a good look at Jencks and it seems close to what I'm looking for. I was getting ready to integrate it into a project, but other issues came up and we avoided having to use JMS for the short term (problems with Oracle's JMS provider). I'd certainly be happy to consider it in the future, along with whatever parts of Spring are designed for this sort of thing.

    A couple of random questions, though:
    1. Has anyone done any performance/reliability analysis of a Jencks/Spring 2.0 type of listener scenario versus an EJB MDB listener scenario?
    2. This is kind of off-topic, but will JEE 1.5 do the same thing for checked JMS exceptions that it does for EJB? My understanding is that the new EJB standard is much closer to Spring's use of unchecked exceptions (at least I recall some of the Hibernate guys saying so in an argument against using Spring). I was curious if they're doing the same with JMS.
  25. MDBs[ Go to top ]

    Has anyone done any performance/reliability analysis of a Jencks/Spring 2.0 type of listener scenario versus an EJB MDB listener scenario?2.

    MDBs should be a little slower, but since 99% of the cost is in the JMS itself, there will be little measurable difference between the various implementations (if they are all over the same JMS impl), as long as they don't do anything stupid.

    Peace,

    Cameron Purdy
    Tangosol Coherence: Clustered Shared Memory for Java
  26. I disagree that JMS is not easy. It's not as easy as it could be, but it is definitely easy. But you do bring some interesting points about the Spring JMS benefits:

    1. Unchecked exceptions. I agree with you, but I am not sure if we are right. The jury is still out there on unchecked vs. checked exceptions.

    2. Transparency between versions is clearly an advantage, but one rarely used.

    3. But even without spring, JNDI specifics needn't be in your code. JNDI Properties are in your config file and only code you have is new InitialContext(properties). You would normally abstract the lookups anyway. (Abstracting the lookups, and a small set of JMS functionality that you use is I think a better option that using a third party full abstraction of JMS. This is even worse if you are talking about a JMS implementation which is already a layer on top of another product e.g. MQ Series.)

    4. Vendor portability, that's why we have JMS in the first place. If you pull your connection properties out of your code, it's already there.

    Your Holy Grail already exists in a number of implementations, some of them on top of JMS. It is not always the best idea to expand a specification to include all possible use cases. Some should be left to us developers.
    I really love it when people show how "hardcore" they are by spitting on everything related to {insert popular whipping boy here}. I don't find that JMS is "already easy enough". Dependencies on JNDI, MDBs, etc., make it a pain to use in a lot of cases. Spring JMS, from what I can tell, brings the following to the table:1. A more sane, unchecked exception hierarchy (same as Spring data access does).2. Code transparency between 1.0 and 1.1 APIs3. Abstraction of connection, so JNDI-specifics don't have to reside in your code (which is not where they belong).4. Vendor portability, because connections are handled in a consistent, abstracted way.Abstraction layers like this aren't always necessary, but when they provide utility, they should be recognized and not assaulted because they don't provide that utility in your specific situation.The holy grail for this to me would be the ability to have JMS listeners, like MDBs, but without dealing with EJBs at all. That way, you could deploy listeners in something like Tomcat with relative ease, or (another example of vendor portability), not have to worry about whether your app is running in Tomcat, Oracle, BEA, etc. That's not a need for all applications, but when it is necessary, it's very helpful for these kinds of abstractions.
  27. I think one great example of vendor portability is going between just about any commercial server out there and Tomcat. The JNDI implementation of Tomcat is a pain to use, and all of the properties are slightly different (if I'm not mistaken, Tomcat doesn't like it unless you have "java:env/" in front of everything). By abstracting out JNDI and using dependency injection, I can get a self-contained app working on Tomcat just as easily as other servers, without dealing with a lot of server-specific JNDI setup. Of course, it doesn't save me vendor-specific JMS configuration, but it is one less hassle.

    I agree with you that I'm not _sure_ that we're right about checked versus unchecked exceptions, but I can tell you that after spending the past few years working primarily with unchecked (thanks to Spring DAO, my own use of unchecked exceptions, and working in .NET), I really don't miss checked exceptions. At this point, I'd have to hear a really compelling argument for me to muck up my code with the mess that they can bring. So while I'm not sure, I'm certainly getting there in a hurry.
  28. Take a look at the JMSML explained at
    http://dev2dev.bea.com/pub/a/2004/01/JMSML_WhitePaper.html
    that was developed way before Spring JMS template and shows how to hide JMS/JMX Java API behind XML.
  29. Use Lingo Instead[ Go to top ]

    If you don't want to write JMS code at all, take a look at Lingo. Lingo is an extension to the Spring Remoting APIs that will wrap POJOs with JMS. I recently delivered a talk on how to do this at the Boulder Java Users's Group and included sample code that demonstrates this completely. The presentation and the sample code will be posted soon.