recommended connection method for outside clients to connect to JMS queues
We have our clients in an extranet based 开发者_如何学Cenvironment that need to connect to our JMS queues. Should they be able to just lookup our queues and connectionFactories in the JNDI space. I mean what is the recommended and scalable approach...
During initialisation, client applications will need to access a ConnectionFactory
and Destination
(the base type for both Queue
and Topic
) object. Collectively, such types are called administered objects, and the JMS specification states that they should implement the javax.naming.Referenceable
and java.io.Serializable
interfaces.
This means you can make administered objects available to clients not only via a naming service but also via other mechanisms. For example, you could serialize the administered objects and store them in files, transmit the serialized objects as attachments to email messages, make .jso
(Java Serialized Object) files available on a web/FTP server, and so on. Such an approach might be useful if your concern about extranet clients is that they won't know the contact details of your internal naming service.
But this doesn't really answer your question of which is the best technology to make administered objects available to JMS clients? A naming service? Serialised-object files on a shared file system? A web or FTP server? A database? The answer is that there isn't a "universally best" way. Some organisations will standardise on using one technology, and other organisations will prefer to use another technology. If you are writing a JMS client that will be used in many organisations, then you could make your client flexible in how it accesses administered objects. You can do this by implementing a method with a signature like the following:
public Object importObject(String instructions);
The implementation of that method should look at the start of instructions
to figure out which technology it should use to retrieve an object. For example:
obj1 = importObject("naming#path/in/naming/service");
obj2 = importObject("file#path/to/file.jso");
obj3 = importObject("exec#command to execute");
(In practice, the instructions should be obtained from, say, a command-line argument or a configuration file rather than being hard-coded into an application.)
The "exec#..."
variant shown above will make it possible to execute an arbitrary shell command that can retrieve a .jso
file from a web or FTP server (perhaps using curl), a database or whatever is most convenient for the user. Years ago, I wrote a similar-ish type of utility function for another middleware technology (CORBA), and the flexibility it offered turned out to be very useful. You can read a bit about my CORBA utility function here.
Another issue to be aware of (and one that @skaffman mentioned in a comment) is that although the JMS specification defines an API, it does not define an on-the-wire protocol. Because of this, there is typically no interoperability between different JMS products. So, if your company-internal JMS applications are built with product X, then the company-external JMS clients will also need to be built with product X. Having said that, some vendors might sell a "bridge" that can accept incoming messages via the on-the-wire protocol used by product X and then retransmit the messages using the on-the-wire protocol of product Y. That is one way to provide interoperability between different JMS products.
Disclaimer: don't let the verbosity of this answer fool you into thinking that I am a JMS expert. I actually have very limited experience of using JMS, so if somebody adds a comment saying that my advice is flawed, then they are probably right.
精彩评论