JMS interfaces and implementations
JMS API declare many General and concrete Interfaces (e.g., Connection vs. QueueConnection). It is documented that the best practice is to use the general interfaces (e.g. Session and not QueueSession). If my application is using both queues and topics and I'm going general, that is: Connection-->Session-->Topic/Queue, and suppose to support all JMS implementations (TiBCO, WebLogic, Websphere etc...) can I assume that using general entities will work for both types out-of-the-box (queues and topic)?
To emphasize my point: can I assume all implementers do implem开发者_如何学编程ent the java.jms.Connection interface and can work in general matter for both types?
Thanks, Guy
the java.jmx.Connection is not optional in JMS 1.1 specification so a valid implementation should work. Most of the optional stuff in JMS is listed in chapter 8 "JMS Application Server Facilities" of the JMS 1.1 spec.
One notable point is that ExceptionListener for a Connection is optional according to the spec.
I guess the main point here is that you really should review your design and implementation against the spec to make sure you are not relying on any optional features and you should be reasonably safe in having a portable implementation.
I'm not understanding why in the previous response and discussion there is an assumption that non-durable subscriptions are not portable. Here's a code sample (download link) of one that is both non-durable and JMS 1.1 compliant.
session = connection.createSession(transacted, Session.AUTO_ACKNOWLEDGE);
myDest = (Destination)ctx.lookup(dLookup);
MessageConsumer myConsumer = session.createConsumer(myDest);
Message inMessage = null;
do {
inMessage = myConsumer.receive(10000);
if( inMessage instanceof TextMessage ) {
System.out.println( "\n" + "Got message: "+((TextMessage) inMessage).getText());
}
session.commit();
} while ( inMessage != null );
myConsumer.close();
Not only is the subscriber non-durable in the previous example, but it doesn't matter whether it is a topic or a queue that is retrieved from the JNDI lookup. The link above is to an article with working code samples and JNDI objects written for WMQ v6 but which work equally well on WMQ v7 (but with slightly different setup at the QMgr since pub/sub no longer requires a separate broker component).
Aside from that, the original responder is correct in that as long as the app conforms to the JMS spec, it should run in any JMS compliant transport. Insomuch as that is true, it does not take into account that differences in the vendor's transport implementation bubble up through the JMS abstraction to impact your code.
For example, JMS provides a multi-level exception where the top level is the JMS exception and the next level is the linked exception. It is the linked exception in which the vendor can place vendor-specific error codes. For example, in WMQ you might get a linked exception indicating that the queue is full or a linked exception telling you that the queue is damaged. One of these is transient and retry behavior is appropriate while the other indicates a fatal error. If the app does not understand the errors in the linked exception, it cannot tell the difference.
Some apps intended to be portable deal with this by simply treating all exceptions as fatal. They close all objects and connections and reinitialize. I've also seen an approach where the developer gives up all attempts at portability and looks in the linked exceptions for vendor-specific codes. Somewhere between those approaches are shops that have vendor-specific shims or sub-classes that wrap JMS objects so the app can remain portable but still respond appropriately to vendor-specific exceptions.
Even assuming that these things are not an issue, it is still important to understand how the vendor has interpreted and implemented the spec. For example, some transports seamlessly fail clients over when a broker fails. Developers might rely on that behavior and omit any reconnect logic from their app. But what if the problem is not the broker but rather is at the network connection at the client? How long will the app hang attempting to fail over and what does the user see? The spec does not address these issues and portability only gets you so far.
So by all means understand the spec and write portable code, but also understand the vendor's implementation of the spec and where the boundaries of portability lie with that implementation. In any case, that boundary does not lie between durable and non-durable subscriptions.
精彩评论