-
1. Re: AS7.1 JMS SSL via JBoss remoting
jbertram Feb 8, 2012 2:20 PM (in response to ned233)Can you clarify your question? You indicate that you were using SSL for your HornetQ destinations (using an SSL acceptor), but now you are using port 4447? Why did this change?
To be clear, HornetQ doesn't use JBoss Remoting as its network transport. It uses Netty. You can configure the acceptor in your standalone-full.xml per the HornetQ documentation.
-
2. Re: AS7.1 JMS SSL via JBoss remoting
ned233 Feb 8, 2012 3:19 PM (in response to jbertram)I think I have it figured out. I am connecting to port 4447 to get my remote JNDI ConnectionFactory (as is described here: https://issues.jboss.org/browse/AS7-1338).
So, I have created a corresponding ConnectionFactory, like this:
<connection-factory name="RemoteConnectionFactory">
<connectors>
<connector-ref connector-name="netty-ssl-connector"/>
</connectors>
<entries>
<entry name="java:jboss/exported/jms/RemoteConnectionFactory"/>
</entries>
</connection-factory>
All I had to do to get this working was to change my connector reference within this connection factory to point to my SSL connector, and everything works now. Sorry for the confusion.
Ed
-
3. Re: AS7.1 JMS SSL via JBoss remoting
jbertram Feb 8, 2012 3:40 PM (in response to ned233)That looks perfect. Glad to you got this sorted out.
Remember, JNDI connections are 100% independent of JMS connections. They use different sockets, different protocols, different implementations, etc.
-
4. Re: AS7.1 JMS SSL via JBoss remoting
doug.j.martin Aug 15, 2012 10:31 PM (in response to jbertram)Looks like you solved the issue I’m currently having. Unfortunately for me you didn’t have the need to post any of your configuration and code snippets, which I’d be interested in seeing.
I recreated the issue I’m having with a simple example client:
public class HelloWorldJMSClient {
// Set up all the default values
private static final String DEFAULT_MESSAGE = "Hello, World!";
private static final String DEFAULT_CONNECTION_FACTORY = "jms/RemoteConnectionFactory";
private static final String DEFAULT_DESTINATION = "jms/queue/test";
private static final String DEFAULT_MESSAGE_COUNT = "1";
private static final String DEFAULT_USERNAME = "user";
private static final String DEFAULT_PASSWORD = "password";
private static final String INITIAL_CONTEXT_FACTORY = "org.jboss.naming.remote.client.InitialContextFactory";
private static final String PROVIDER_URL = "remote://localhost:4447";
public static void main(final String[] args) throws Exception {
ConnectionFactory connectionFactory = null;
Connection connection = null;
Session session = null;
MessageProducer producer = null;
MessageConsumer consumer = null;
Destination destination = null;
TextMessage message = null;
Context context = null;
try {
// Set up the context for the JNDI lookup
final Properties env = new Properties();
env.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
env.put(Context.PROVIDER_URL, System.getProperty(Context.PROVIDER_URL, PROVIDER_URL));
env.put(Context.SECURITY_PRINCIPAL, System.getProperty("username", DEFAULT_USERNAME));
env.put(Context.SECURITY_CREDENTIALS, System.getProperty("password", DEFAULT_PASSWORD));
context = new InitialContext(env);
// Perform the JNDI lookups
final String connectionFactoryString = System.getProperty("connection.factory", DEFAULT_CONNECTION_FACTORY);
log.info("Attempting to acquire connection factory \"" + connectionFactoryString + "\"");
connectionFactory = (ConnectionFactory) context.lookup(connectionFactoryString);
log.info("Found connection factory \"" + connectionFactoryString + "\" in JNDI");
final String destinationString = System.getProperty("destination", DEFAULT_DESTINATION);
log.info("Attempting to acquire destination \"" + destinationString + "\"");
destination = (Destination) context.lookup(destinationString);
log.info("Found destination \"" + destinationString + "\" in JNDI");
// Create the JMS connection, session, producer, and consumer
connection = connectionFactory.createConnection(System.getProperty("username", DEFAULT_USERNAME), System.getProperty("password", DEFAULT_PASSWORD));
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
producer = session.createProducer(destination);
consumer = session.createConsumer(destination);
connection.start();
final int count = Integer.parseInt(System.getProperty("message.count", DEFAULT_MESSAGE_COUNT));
final String content = System.getProperty("message.content", DEFAULT_MESSAGE);
log.info("Sending " + count + " messages with content: " + content);
// Send the specified number of messages
for (int i = 0; i < count; i++) {
message = session.createTextMessage(content);
producer.send(message);
}
// Then receive the same number of messaes that were sent
for (int i = 0; i < count; i++) {
message = (TextMessage) consumer.receive(5000);
log.info("Received message with content " + message.getText());
}
} catch (final Exception e) {
log.severe(e.getMessage());
throw e;
} finally {
if (context != null) {
context.close();
}
// closing the connection takes care of the session, producer, and consumer
if (connection != null) {
connection.close();
}
}
}
}
Get the following exceptions when I run it:
Aug 15, 2012 6:57:00 PM org.jboss.remoting3.remote.RemoteConnection handleException
ERROR: JBREM000200: Remote connection failed: java.io.IOException: Client starting STARTTLS but channel doesn't support SSL
Aug 15, 2012 6:57:00 PM org.jboss.samples.hq.test.HelloWorldJMSClient main
SEVERE: Failed to create remoting connection
Exception in thread "main" javax.naming.NamingException: Failed to create remoting connection [Root exception is java.lang.RuntimeException: java.io.IOException: Client starting STARTTLS but channel doesn't support SSL]
at org.jboss.naming.remote.client.ClientUtil.namingException(ClientUtil.java:36)
at org.jboss.naming.remote.client.InitialContextFactory.getInitialContext(InitialContextFactory.java:121)
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:667)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:288)
at javax.naming.InitialContext.init(InitialContext.java:223)
at javax.naming.InitialContext.<init>(InitialContext.java:197)
at org.jboss.samples.hq.test.HelloWorldJMSClient.main(HelloWorldJMSClient.java:64)
Caused by: java.lang.RuntimeException: java.io.IOException: Client starting STARTTLS but channel doesn't support SSL
at org.jboss.naming.remote.protocol.IoFutureHelper.get(IoFutureHelper.java:87)
at org.jboss.naming.remote.client.NamingStoreCache.getRemoteNamingStore(NamingStoreCache.java:56)
at org.jboss.naming.remote.client.InitialContextFactory.getOrCreateCachedNamingStore(InitialContextFactory.java:166)
at org.jboss.naming.remote.client.InitialContextFactory.getOrCreateNamingStore(InitialContextFactory.java:139)
at org.jboss.naming.remote.client.InitialContextFactory.getInitialContext(InitialContextFactory.java:104)
... 5 more
Caused by: java.io.IOException: Client starting STARTTLS but channel doesn't support SSL
at org.jboss.remoting3.remote.ClientConnectionOpenListener$StartTls.handleEvent(ClientConnectionOpenListener.java:488)
at org.jboss.remoting3.remote.ClientConnectionOpenListener$StartTls.handleEvent(ClientConnectionOpenListener.java:427)
at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:72)
at org.xnio.channels.TranslatingSuspendableChannel.handleReadable(TranslatingSuspendableChannel.java:189)
at org.xnio.channels.TranslatingSuspendableChannel$1.handleEvent(TranslatingSuspendableChannel.java:103)
at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:72)
at org.xnio.nio.NioHandle.run(NioHandle.java:90)
at org.xnio.nio.WorkerThread.run(WorkerThread.java:184)
at ...asynchronous invocation...(Unknown Source)
at org.jboss.remoting3.EndpointImpl.doConnect(EndpointImpl.java:270)
at org.jboss.remoting3.EndpointImpl.doConnect(EndpointImpl.java:251)
at org.jboss.remoting3.EndpointImpl.connect(EndpointImpl.java:349)
at org.jboss.remoting3.EndpointImpl.connect(EndpointImpl.java:333)
at org.jboss.naming.remote.client.EndpointCache$EndpointWrapper.connect(EndpointCache.java:105)
at org.jboss.naming.remote.client.NamingStoreCache.getRemoteNamingStore(NamingStoreCache.java:55)
... 8 more
Configuration Snippets:
<subsystem xmlns="urn:jboss:domain:messaging:1.1"> <hornetq-server> <persistence-enabled>true</persistence-enabled> <journal-file-size>102400</journal-file-size> <journal-min-files>2</journal-min-files> <connectors> <netty-connector name="netty-ssl-connector" socket-binding="messaging"> <param key="ssl-enabled" value="true"/> <param key="key-store-path" value="xxx.jks"/> <param key="key-store-password" value="password"/> </netty-connector> ... </connectors> <acceptors> <netty-acceptor name="netty-ssl-acceptor" socket-binding="messaging"> <param key="ssl-enabled" value="true"/> <param key="key-store-path" value="xxx.jks"/> <param key="key-store-password" value="changeme"/> <param key="trust-store-path" value="xxx.jks"/> <param key="trust-store-password" value="password"/> </netty-acceptor> ... </acceptors> ... <jms-connection-factories> ... <connection-factory name="RemoteConnectionFactory"> <connectors> <connector-ref connector-name="netty-ssl-connector"/> </connectors> <entries> <entry name="java:jboss/exported/jms/RemoteConnectionFactory"/> </entries> </connection-factory> ... </jms-connection-factories> </hornetq-server> </subsystem> <socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}"> <socket-binding name="messaging" port="5445"/> <socket-binding name="remoting" port="4447"/> </socket-binding-group> I've tried adding host and port to the acceptor / connector definitions with no luck.
I've tried adding a unique socked binding on a different port than messaging and remoting with no luck.
Guessing this is a simple configuration problem but I'd greatly appreciate some help.
Thanks in advance,
Doug
-
5. Re: AS7.1 JMS SSL via JBoss remoting
jbertram Aug 16, 2012 10:15 AM (in response to doug.j.martin)The first thing to note is that you aren't even making it to HornetQ. Your client is failing during the JNDI look-up. Unfortunately I don't know much about the server-side configuration of JNDI, but it looks like theres a problem with the way you've set up security.
-
6. Re: AS7.1 JMS SSL via JBoss remoting
doug.j.martin Aug 16, 2012 12:54 PM (in response to jbertram)Justin, you nailed it! It was a JNDI look-up issue. Must appreciated, thanks.
-
7. Re: AS7.1 JMS SSL via JBoss remoting
ybxiang.china Oct 5, 2012 2:03 AM (in response to doug.j.martin)Hi Martin,
I do everything as you, but still get bellow excepton:
!MESSAGE (Timezone is CST.) ;5340; org.jboss.remoting.remote.connection: "JBREM000200: Remote connection failed: java.io.IOException: Client starting STARTTLS but channel doesn't support SSL"
Would you please post your client code???
Thank you VERY much.
I spend many hours on this issue.
My configuration:
<subsystem xmlns="urn:jboss:domain:messaging:1.3"> <hornetq-server> <persistence-enabled>true</persistence-enabled> <journal-file-size>102400</journal-file-size> <journal-min-files>2</journal-min-files> <connectors> <netty-connector name="netty-ssl-connector" socket-binding="messaging"> <param key="ssl-enabled" value="true"/> <param key="key-store-path" value="server.keystore"/> <param key="key-store-password" value="ybxiang_keystore_password"/> </netty-connector> <netty-connector name="netty-throughput" socket-binding="messaging-throughput"> <param key="batch-delay" value="50"/> </netty-connector> <in-vm-connector name="in-vm" server-id="0"/> </connectors> <acceptors> <netty-acceptor name="netty-ssl-acceptor" socket-binding="messaging"> <param key="ssl-enabled" value="true"/> <param key="key-store-path" value="server.keystore"/> <param key="key-store-password" value="ybxiang_keystore_password"/> <param key="trust-store-path" value="client.truststore"/> <param key="trust-store-password" value="ybxiang_truststore_password"/> </netty-acceptor> <netty-acceptor name="netty-throughput" socket-binding="messaging-throughput"> <param key="batch-delay" value="50"/> <param key="direct-deliver" value="false"/> </netty-acceptor> <in-vm-acceptor name="in-vm" server-id="0"/> </acceptors> <security-settings> <security-setting match="#"> <permission type="send" roles="guest"/> <permission type="consume" roles="guest"/> <permission type="createNonDurableQueue" roles="guest"/> <permission type="deleteNonDurableQueue" roles="guest"/> </security-setting> </security-settings> <address-settings> <!--default for catch all--> <address-setting match="#"> <dead-letter-address>jms.queue.DLQ</dead-letter-address> <expiry-address>jms.queue.ExpiryQueue</expiry-address> <redelivery-delay>0</redelivery-delay> <max-size-bytes>10485760</max-size-bytes> <address-full-policy>BLOCK</address-full-policy> <message-counter-history-day-limit>10</message-counter-history-day-limit> </address-setting> </address-settings> <jms-connection-factories> <connection-factory name="InVmConnectionFactory"> <connectors> <connector-ref connector-name="in-vm"/> </connectors> <entries> <entry name="java:/ConnectionFactory"/> </entries> </connection-factory> <connection-factory name="RemoteConnectionFactory"> <connectors> <connector-ref connector-name="netty-ssl-connector"/> </connectors> <entries> <entry name="java:jboss/exported/jms/RemoteConnectionFactory"/> </entries> </connection-factory> <pooled-connection-factory name="hornetq-ra"> <transaction mode="xa"/> <connectors> <connector-ref connector-name="in-vm"/> </connectors> <entries> <entry name="java:/JmsXA"/> </entries> </pooled-connection-factory> </jms-connection-factories> <jms-destinations> <jms-queue name="testQueue"> <entry name="queue/test"/> <entry name="java:jboss/exported/jms/queue/test"/> </jms-queue> <jms-topic name="testTopic"> <entry name="topic/test"/> <entry name="java:jboss/exported/jms/topic/test"/> </jms-topic> </jms-destinations> </hornetq-server> </subsystem> I can send JMS in an ejb on the server side successfully:
private void sendMessageMethod1() { Context context = null; ConnectionFactory connectionFactory = null; Connection connection = null; // try { context = new InitialContext(); /** * * http://stackoverflow.com/questions/7515220/how-to-get-the-new-jndi-names-esp-connectionfactory */ connectionFactory = (ConnectionFactory) context.lookup("java:/ConnectionFactory"); Queue queue = (Queue) context.lookup("queue/test"); connection = connectionFactory.createConnection(); Session session = connection.createSession( false,//transacted Session.AUTO_ACKNOWLEDGE); MessageProducer publisher = session.createProducer(queue); connection.start(); String message = "Hello AS 7(method1) !"; TextMessage textMessage = session.createTextMessage(message); publisher.send(textMessage); log.info("Message is sent: "+message); } catch (Exception exc) { exc.printStackTrace(); } finally { if (connection != null) { try { connection.close(); } catch (JMSException e) { e.printStackTrace(); } } } } And receive the message successfully.
NOTE: I put client.truststore and server.keystore in jboss-as-7.2.0.Alpha1\bin.
client.truststore only contains erver.keystore's public key.
My EJB client can call EJB over SSL successfully with client.truststore. My client code:
try{ Properties p = new Properties(); p.put("remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED", "true"); p.put("remote.connections", "default"); p.put("remote.connection.default.host", serverIP); p.put("remote.connection.default.port", "4447"); p.put("remote.connection.default.username", username); p.put("remote.connection.default.password", password); p.put("remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS", "false"); p.put("remote.connection.default.connect.options.org.xnio.Options.SASL_DISALLOWED_MECHANISMS", "JBOSS-LOCAL-USER"); p.put("remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT", "false"); p.put("remote.connection.default.connect.options.org.xnio.Options.SSL_STARTTLS", "true"); p.put("remote.connection.default.connect.timeout", "30000");//for xnio EJBClientConfiguration cc = new PropertiesBasedEJBClientConfiguration(p); ContextSelector<EJBClientContext> selector = new ConfigBasedEJBClientContextSelector(cc); EJBClientContext.setSelector(selector); EJBClientContext.getCurrent().registerInterceptor(0,new ClientSessionTokenInterceptor()); EJBClientContext.getCurrent().registerInterceptor(1,new ClientExceptionInterceptor()); Properties props = new Properties(); props.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming"); props.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory"); props.put(Context.PROVIDER_URL, System.getProperty(Context.PROVIDER_URL, "remote://"+serverIP+":4447")); props.put(Context.SECURITY_PRINCIPAL, username); props.put(Context.SECURITY_CREDENTIALS, password); InitialContext context = new InitialContext(props); securedRemoteSessionProxy = (ISecuredRemoteSession)context.lookup(jndiName); // testJms();//Wrong: throw exception!!! testJms2(context);//Wrong: throw exception!!! }catch(Exception e){ log.error(e); throw ConnectionToServerFailedException.INSTANCE; } private static final String DEFAULT_MESSAGE = "Hello, World!"; private static final String DEFAULT_CONNECTION_FACTORY = "jms/RemoteConnectionFactory"; private static final String DEFAULT_DESTINATION = "jms/queue/test"; private static final String DEFAULT_MESSAGE_COUNT = "1"; private static final String DEFAULT_USERNAME = "admin"; private static final String DEFAULT_PASSWORD = "admin123"; private static final String INITIAL_CONTEXT_FACTORY = "org.jboss.naming.remote.client.InitialContextFactory"; private static final String PROVIDER_URL = "remote://192.168.1.100:4447"; public static void testJms() throws Exception { ConnectionFactory connectionFactory = null; Connection connection = null; Session session = null; MessageProducer producer = null; MessageConsumer consumer = null; Destination destination = null; TextMessage message = null; Context context = null; try { // Set up the context for the JNDI lookup final Properties env = new Properties(); env.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY); env.put(Context.PROVIDER_URL, System.getProperty(Context.PROVIDER_URL, PROVIDER_URL)); env.put(Context.SECURITY_PRINCIPAL, System.getProperty("username", DEFAULT_USERNAME)); env.put(Context.SECURITY_CREDENTIALS, System.getProperty("password", DEFAULT_PASSWORD)); context = new InitialContext(env); // Perform the JNDI lookups String connectionFactoryString = System.getProperty("connection.factory", DEFAULT_CONNECTION_FACTORY); log.info("Attempting to acquire connection factory \"" + connectionFactoryString + "\""); connectionFactory = (ConnectionFactory) context.lookup(connectionFactoryString); log.info("Found connection factory \"" + connectionFactoryString + "\" in JNDI"); String destinationString = System.getProperty("destination", DEFAULT_DESTINATION); log.info("Attempting to acquire destination \"" + destinationString + "\""); destination = (Destination) context.lookup(destinationString); log.info("Found destination \"" + destinationString + "\" in JNDI"); // Create the JMS connection, session, producer, and consumer connection = connectionFactory.createConnection(System.getProperty("username", DEFAULT_USERNAME), System.getProperty("password", DEFAULT_PASSWORD)); session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); producer = session.createProducer(destination); consumer = session.createConsumer(destination); connection.start(); int count = Integer.parseInt(System.getProperty("message.count", DEFAULT_MESSAGE_COUNT)); String content = System.getProperty("message.content", DEFAULT_MESSAGE); log.info("Sending " + count + " messages with content: " + content); // Send the specified number of messages for (int i = 0; i < count; i++) { message = session.createTextMessage(content); producer.send(message); } // Then receive the same number of messaes that were sent for (int i = 0; i < count; i++) { message = (TextMessage) consumer.receive(5000); log.info("Received message with content " + message.getText()); } } catch (Exception e) { log.error(e); //throw e; } finally { if (context != null) { context.close(); } // closing the connection takes care of the session, producer, and consumer if (connection != null) { connection.close(); } } } public static void testJms2(InitialContext context) throws Exception { ConnectionFactory connectionFactory = null; Connection connection = null; Session session = null; MessageProducer producer = null; MessageConsumer consumer = null; Destination destination = null; TextMessage message = null; try { // Perform the JNDI lookups String connectionFactoryString = System.getProperty("connection.factory", DEFAULT_CONNECTION_FACTORY); log.info("Attempting to acquire connection factory \"" + connectionFactoryString + "\""); connectionFactory = (ConnectionFactory) context.lookup(connectionFactoryString); log.info("Found connection factory \"" + connectionFactoryString + "\" in JNDI"); String destinationString = System.getProperty("destination", DEFAULT_DESTINATION); log.info("Attempting to acquire destination \"" + destinationString + "\""); destination = (Destination) context.lookup(destinationString); log.info("Found destination \"" + destinationString + "\" in JNDI"); // Create the JMS connection, session, producer, and consumer connection = connectionFactory.createConnection(System.getProperty("username", DEFAULT_USERNAME), System.getProperty("password", DEFAULT_PASSWORD)); session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); producer = session.createProducer(destination); consumer = session.createConsumer(destination); connection.start(); int count = Integer.parseInt(System.getProperty("message.count", DEFAULT_MESSAGE_COUNT)); String content = System.getProperty("message.content", DEFAULT_MESSAGE); log.info("Sending " + count + " messages with content: " + content); // Send the specified number of messages for (int i = 0; i < count; i++) { message = session.createTextMessage(content); producer.send(message); } // Then receive the same number of messaes that were sent for (int i = 0; i < count; i++) { message = (TextMessage) consumer.receive(5000); log.info("Received message with content " + message.getText()); } } catch (Exception e) { log.error(e); } finally { if (connection != null) { connection.close(); } } } -
8. Re: AS7.1 JMS SSL via JBoss remoting
jesper.s.karlsen Dec 16, 2013 4:34 PM (in response to ybxiang.china)Hi xiang yingbing,
Thanks for your reply. We found a workable solution though - please see thread Creating SSL enabled InitialContext with Spring JndiTemplate
We simply create the connection programatically and use it inside spring.
Thanks for your help though.
cheers,
Jesper
-
9. Re: AS7.1 JMS SSL via JBoss remoting
nguyennhatkhanh206 Sep 21, 2014 11:33 PM (in response to jesper.s.karlsen)Is there any solutions if we do not use Spring?