I'm having trouble connecting to a message broker (HornetQ 2.4.0-beta1) using
the Qpid JMS-over-AMQP client
(http://qpid.apache.org/releases/qpid-0.24/programming/book/QpidJMS.html).
I've run into two major roadblocks; for the first, I think that I have a
work-around, but the second is still frustrating my progress:
~~
QUESTION 1
~~
The first problem I'm having is that the specified connection factory
(org.apache.qpid.jndi.PropertiesFileInitialContextFactory) does not appear to
support programmatic declaration of the JNDI properties, as is implied in the
documentation. The documentation indicates that these properties:
java.naming.factory.initial =
org.apache.qpid.jndi.PropertiesFileInitialContextFactory
connectionfactory.qpidConnectionfactory =
amqp://guest:guest@clientid/test?brokerlist='tcp://localhost:5672'
destination.topicExchange = amq.topic
are loaded from a file on the classpath *outside* of the Qpid client library,
then the InitialContext is constructed from the resulting Properties object:
Properties properties = new Properties();
properties.load(this.getClass().getResourceAsStream("hello.properties"));
Context context = new InitialContext(properties);
However, my attempt to duplicate this approach resulted in a NamingException
with a "No Provider URL specified" message. Examination of the source of
PropertiesFileInitialContextFactory
(http://grepcode.com/file/repo1.maven.org/maven2/org.apache.qpid/qpid-amqp-1-0-client-jms/0.22/org/apache/qpid/amqp_1_0/jms/jndi/PropertiesFileInitialContextFactory.java)
shows why: the getInitialContext(Hashtable) method requires a property to be
defined with key Context.PROVIDER_URL ("java.naming.provider.url").
Furthermore, the method requires that the value of that property point to a
file path on the local file system.
As far as I can tell, the documentation never indicates a need for
java.naming.provider.url to be defined, nor does it require that the value
refer to a local file; the implication from the docs is that properties can be
provided via the Map provided as a parameter.
I resolved this first problem by creating a subclass of
PropertiesFileInitialContextFactory which overrides
getInitialContext(Hashtable) to eliminate the part of
getInitialContext(Hashtable) which refers to the Context.PROVIDER_URL property
(https://github.com/sumitsu/qpidamqpjmstest/blob/master/src/test/java/net/sumitsu/qpidamqpjmstest/hornetqamqp/ProgrammaticQpidAMQContextFactory.java),
but I couldn't find any documentation suggesting that I'd have to do that; am
I missing something?
~~
QUESTION 2
~~
Once that problem was resolved, the second problem is that the client library
seems to be ignoring the brokerlist provided as part of the
connectionfactory.<jndiName> parameter; instead, it seems to want to treat the
clientId as if it were the remote host, leading to an UnknownHostException; for
these connectivity properties:
connectionfactory.CnxnFactory-9a59fbd6-4564-84b6-973e-69e4e3d1ee45=amqp://guest:guest@clientid/testvhost?brokerlist='tcp://localhost:10005'
java.naming.factory.initial=net.sumitsu.qpidamqpjmstest.hornetqamqp.ProgrammaticQpidAMQContextFactory
queue.Queue-9a59fbd6-4564-84b6-973e-69e4e3d1ee45=jms.queue.TestQueue20131007
I get this stack trace:
javax.jms.JMSException: java.net.UnknownHostException: clientid
at
org.apache.qpid.amqp_1_0.jms.impl.ConnectionImpl.connect(ConnectionImpl.java:112)
at
org.apache.qpid.amqp_1_0.jms.impl.ConnectionImpl.createSession(ConnectionImpl.java:163)
at
org.apache.qpid.amqp_1_0.jms.impl.ConnectionImpl.createSession(ConnectionImpl.java:149)
at
org.apache.qpid.amqp_1_0.jms.impl.ConnectionImpl.createQueueSession(ConnectionImpl.java:405)
at
net.sumitsu.qpidamqpjmstest.hornetqamqp.TestQueuePublisherSimplified.buildProducer(TestQueuePublisherSimplified.java:95)
at
net.sumitsu.qpidamqpjmstest.hornetqamqp.TestQueuePublisherSimplified.<init>(TestQueuePublisherSimplified.java:113)
at
net.sumitsu.qpidamqpjmstest.hornetqamqp.TestQueuePublisherSimplified.main(TestQueuePublisherSimplified.java:127)
Caused by: org.apache.qpid.amqp_1_0.client.ConnectionException:
java.net.UnknownHostException: clientid
at
org.apache.qpid.amqp_1_0.client.Connection.<init>(Connection.java:271)
at
org.apache.qpid.amqp_1_0.client.Connection.<init>(Connection.java:135)
at
org.apache.qpid.amqp_1_0.jms.impl.ConnectionImpl.connect(ConnectionImpl.java:105)
... 6 more
Caused by: java.net.UnknownHostException: clientid
at
java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:178)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:579)
at java.net.Socket.connect(Socket.java:528)
at java.net.Socket.<init>(Socket.java:425)
at java.net.Socket.<init>(Socket.java:208)
at
org.apache.qpid.amqp_1_0.client.Connection.<init>(Connection.java:159)
... 8 more
Using reflection to obtain the private values of the
org.apache.qpid.amqp_1_0.jms.impl.ConnectionImpl
(http://grepcode.com/file/repo1.maven.org/maven2/org.apache.qpid/qpid-amqp-1-0-client-jms/0.22/org/apache/qpid/amqp_1_0/jms/impl/ConnectionImpl.java)
object shortly after the queue session is established produces this result:
_conn=null
_isQueueConnection=true
_isTopicConnection=false
_closeTasks=[]
_host=clientid
_port=5672
_username=guest
_password=guest
_remoteHost=clientid
_ssl=false
_clientId=null
_queuePrefix=null
_topicPrefix=null
_useBinaryMessageId=true
For some reason, the client library seems to be assigning "clientid" to both
_host and _remoteHost (and failing to assign it to _clientId), and consequently
the client tries to establish a broker connection to that ID rather than to a
broker denoted in brokerlist. Am I doing something wrongly here?
For reference, my test code is available here:
https://github.com/sumitsu/qpidamqpjmstest. Any suggestions are appreciated.
Thanks!
Branden Smith
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]