Java通过STOMP+SSL连接AmazonMQ(ActiveMQ后端)使用QueueBrowser时遭遇JMSException问题求助
Got it, let's break down what's causing that JMSException and fix it step by step.
Root Cause
The core issue here is that when using the stomp+ssl protocol, the ActiveMQConnectionFactory automatically injects a wireFormat.host parameter into the connection string—but the Stomp transport factory doesn't recognize this parameter, hence the Invalid connect parameters error. Additionally, you've got two critical configuration mistakes: using the wrong port for Stomp+SSL, and missing necessary SSL truststore setup.
Step 1: Fix the Port Number
Amazon MQ for ActiveMQ uses 61614 as the Stomp over SSL port (61616 is actually the non-SSL port for the OpenWire protocol). Update your PORT variable:
final String PORT = "61614";
Step 2: Add Stomp Dependency
Make sure your project includes the activemq-stomp artifact—this provides the full Stomp transport implementation that the core ActiveMQ library doesn't include by default. If you're using Maven, add this to your pom.xml:
<dependency> <groupId>org.apache.activemq</groupId> <artifactId>activemq-stomp</artifactId> <version><!-- Match your Amazon MQ ActiveMQ version --></version> </dependency>
Step 3: Fix Connection String Parameters
We need to explicitly tell the connection factory to use the Stomp wire format and disable the auto-injected wireFormat.host parameter. Modify your connection string like this:
final String connectionString = PROTOCOL + "://" + HOST + ":" + PORT + "?wireFormat=stomp&wireFormat.host=null";
Alternatively, you can set the wire format directly in code instead of adding it to the URL:
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(connectionString); connectionFactory.setWireFormat(new StompWireFormat());
Step 4: Configure SSL Truststore (Critical for SSL Connections)
Since you're using stomp+ssl, your JVM needs to trust Amazon MQ's SSL certificate. Here are two ways to handle this:
Option 1: Use a Custom Truststore (Production-Grade)
- Download Amazon's root CA certificate (e.g.,
AmazonRootCA1.pem). - Import it into a new truststore using
keytool:keytool -import -alias AmazonRootCA1 -file AmazonRootCA1.pem -keystore my-truststore.jks -storepass changeit - Add these system properties to your code before creating the connection:
System.setProperty("javax.net.ssl.trustStore", "/path/to/your/my-truststore.jks"); System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
Option 2: Disable Certificate Validation (Only for Testing!)
Never use this in production—it skips all SSL certificate checks:
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import java.security.cert.X509Certificate; // Add this code before creating the connection factory TrustManager[] trustAllCerts = new TrustManager[]{ new X509TrustManager() { public X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted(X509Certificate[] certs, String authType) {} public void checkServerTrusted(X509Certificate[] certs, String authType) {} } }; SSLContext sc = SSLContext.getInstance("TLS"); sc.init(null, trustAllCerts, new java.security.SecureRandom()); SSLSocketFactory sslSocketFactory = sc.getSocketFactory(); // Attach the custom SSL socket factory to the connection factory ((ActiveMQConnectionFactory)connectionFactory).setSSLSocketFactory(sslSocketFactory);
Full Fixed Code
Here's the complete, corrected version of your code with all the fixes applied:
import java.util.Enumeration; import javax.jms.Queue; import javax.jms.QueueBrowser; import javax.jms.Session; import javax.jms.ConnectionFactory; import javax.jms.Connection; import org.apache.activemq.ActiveMQConnectionFactory; import org.apache.activemq.transport.stomp.StompWireFormat; public class QueueBrowserExample { public static void main(String[] args) throws Exception { System.out.println("init"); // Configure SSL truststore (replace with your path and password) System.setProperty("javax.net.ssl.trustStore", "/path/to/your/my-truststore.jks"); System.setProperty("javax.net.ssl.trustStorePassword", "changeit"); try { final String PORT = "61614"; final String PROTOCOL = "stomp+ssl"; final String HOST = "xxx.mq.us-east-1.amazonaws.com"; final String connectionString = PROTOCOL + "://" + HOST + ":" + PORT + "?wireFormat=stomp&wireFormat.host=null"; System.out.println("attempt to connect to " + connectionString); ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(connectionString); connectionFactory.setWireFormat(new StompWireFormat()); Connection connection = connectionFactory.createConnection("admin", "admin"); connection.start(); Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); Queue queue = session.createQueue("Test"); QueueBrowser queueBrowser = session.createBrowser(queue); Enumeration msgs = queueBrowser.getEnumeration(); // Optional: Print out messages to verify connection works while (msgs.hasMoreElements()) { javax.jms.Message msg = (javax.jms.Message) msgs.nextElement(); System.out.println("Received message: " + msg); } // Clean up resources queueBrowser.close(); session.close(); connection.close(); } catch (Exception e) { e.printStackTrace(); } } }
Extra Notes
- Ensure your ActiveMQ client version matches the version used by Amazon MQ (check the Amazon MQ console for this info) to avoid compatibility issues.
- Double-check that your
adminuser has permissions to access theTestqueue in Amazon MQ. - Always use a proper truststore in production—disabling certificate validation exposes you to man-in-the-middle attacks.
内容的提问来源于stack exchange,提问作者loretoparisi

