diff --git a/activemq-camel/src/test/java/org/apache/activemq/camel/AMQ2240Test.java b/activemq-camel/src/test/java/org/apache/activemq/camel/AMQ2240Test.java
new file mode 100644
index 0000000000..b8bb003fd3
--- /dev/null
+++ b/activemq-camel/src/test/java/org/apache/activemq/camel/AMQ2240Test.java
@@ -0,0 +1,69 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.camel;
+
+import static org.junit.Assert.*;
+
+import org.apache.activemq.broker.BrokerService;
+import org.apache.activemq.camel.component.ActiveMQComponent;
+import org.apache.camel.CamelContext;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class AMQ2240Test {
+
+ private static final Logger LOG = LoggerFactory.getLogger(AMQ2240Test.class);
+
+ @Test
+ public void testBadVMTransportOptionsJMSPrefix() throws Exception {
+
+ try{
+ final String vmUri = "vm://localhost?" +
+ "jms.redeliveryPolicy.maximumRedeliveries=0&" +
+ "jms.redeliveryPolicy.initialRedeliveryDelay=500&" +
+ "jms.useAsyncSend=false&jms.sendTimeout=ABC&" +
+ "jms.maxXXXXReconnectAttempts=1&jms.timeout=3000";
+
+ LOG.info("creating context with bad URI: " + vmUri);
+ ActiveMQComponent.activeMQComponent(vmUri);
+
+ fail("Should have received an exception from the bad URI.");
+ } catch(Exception e) {
+ // Expected
+ }
+ }
+
+ @Test
+ public void testBadVMTransportOptionsBrokerPrefix() throws Exception {
+ try{
+ final String vmUri = "vm://localhost?" +
+ "broker.XXX=foo&broker.persistent=XXX&broker.useJmx=false";
+
+ LOG.info("creating context with bad URI: " + vmUri);
+ ActiveMQComponent.activeMQComponent(vmUri).start();
+
+ fail("Should have received an exception from the bad URI.");
+ } catch(Exception e) {
+ // Expected
+ }
+ }
+}
diff --git a/activemq-core/src/main/java/org/apache/activemq/ActiveMQConnectionFactory.java b/activemq-core/src/main/java/org/apache/activemq/ActiveMQConnectionFactory.java
index 0007470193..8cc9fd7c25 100755
--- a/activemq-core/src/main/java/org/apache/activemq/ActiveMQConnectionFactory.java
+++ b/activemq-core/src/main/java/org/apache/activemq/ActiveMQConnectionFactory.java
@@ -52,8 +52,8 @@ import org.apache.activemq.util.URISupport.CompositeData;
* Connections.
This class also implements QueueConnectionFactory and
* TopicConnectionFactory. You can use this connection to create both
* QueueConnections and TopicConnections.
- *
- *
+ *
+ *
* @see javax.jms.ConnectionFactory
*/
public class ActiveMQConnectionFactory extends JNDIBaseStorable implements ConnectionFactory, QueueConnectionFactory, TopicConnectionFactory, StatsCapable, Cloneable {
@@ -237,7 +237,7 @@ public class ActiveMQConnectionFactory extends JNDIBaseStorable implements Conne
/**
* Creates a Transport based on this object's connection settings. Separated
* from createActiveMQConnection to allow for subclasses to override.
- *
+ *
* @return The newly created Transport.
* @throws JMSException If unable to create trasnport.
* @author sepandm@gmail.com
@@ -331,7 +331,7 @@ public class ActiveMQConnectionFactory extends JNDIBaseStorable implements Conne
connection.addTransportListener(transportListener);
}
if (exceptionListener != null) {
- connection.setExceptionListener(exceptionListener);
+ connection.setExceptionListener(exceptionListener);
}
if (clientInternalExceptionListener != null) {
connection.setClientInternalExceptionListener(clientInternalExceptionListener);
@@ -363,8 +363,18 @@ public class ActiveMQConnectionFactory extends JNDIBaseStorable implements Conne
// It might be a standard URI or...
try {
- Map map = URISupport.parseQuery(this.brokerURL.getQuery());
- if (buildFromMap(IntrospectionSupport.extractProperties(map, "jms."))) {
+ Map map = URISupport.parseQuery(this.brokerURL.getQuery());
+ Map jmsOptionsMap = IntrospectionSupport.extractProperties(map, "jms.");
+ if (buildFromMap(jmsOptionsMap)) {
+ if (!jmsOptionsMap.isEmpty()) {
+ String msg = "There are " + jmsOptionsMap.size()
+ + " jms options that couldn't be set on the ConnectionFactory."
+ + " Check the options are spelled correctly."
+ + " Unknown parameters=[" + jmsOptionsMap + "]."
+ + " This connection factory cannot be started.";
+ throw new IllegalArgumentException(msg);
+ }
+
this.brokerURL = URISupport.createRemainingURI(this.brokerURL, map);
}
@@ -376,7 +386,17 @@ public class ActiveMQConnectionFactory extends JNDIBaseStorable implements Conne
// It might be a composite URI.
try {
CompositeData data = URISupport.parseComposite(this.brokerURL);
- if (buildFromMap(IntrospectionSupport.extractProperties(data.getParameters(), "jms."))) {
+ Map jmsOptionsMap = IntrospectionSupport.extractProperties(data.getParameters(), "jms.");
+ if (buildFromMap(jmsOptionsMap)) {
+ if (!jmsOptionsMap.isEmpty()) {
+ String msg = "There are " + jmsOptionsMap.size()
+ + " jms options that couldn't be set on the ConnectionFactory."
+ + " Check the options are spelled correctly."
+ + " Unknown parameters=[" + jmsOptionsMap + "]."
+ + " This connection factory cannot be started.";
+ throw new IllegalArgumentException(msg);
+ }
+
this.brokerURL = data.toURI();
}
} catch (URISyntaxException e) {
@@ -503,7 +523,7 @@ public class ActiveMQConnectionFactory extends JNDIBaseStorable implements Conne
/**
* Set true if always require messages to be sync sent
- *
+ *
* @param alwaysSyncSend
*/
public void setAlwaysSyncSend(boolean alwaysSyncSend) {
@@ -542,7 +562,7 @@ public class ActiveMQConnectionFactory extends JNDIBaseStorable implements Conne
* Enables or disables whether or not queue consumers should be exclusive or
* not for example to preserve ordering when not using Message Groups
- *
+ *
* @param exclusiveConsumer
*/
public void setExclusiveConsumer(boolean exclusiveConsumer) {
@@ -564,7 +584,7 @@ public class ActiveMQConnectionFactory extends JNDIBaseStorable implements Conne
public MessageTransformer getTransformer() {
return transformer;
}
-
+
/**
* @return the sendTimeout
*/
@@ -578,7 +598,7 @@ public class ActiveMQConnectionFactory extends JNDIBaseStorable implements Conne
public void setSendTimeout(int sendTimeout) {
this.sendTimeout = sendTimeout;
}
-
+
/**
* @return the sendAcksAsync
*/
@@ -592,7 +612,7 @@ public class ActiveMQConnectionFactory extends JNDIBaseStorable implements Conne
public void setSendAcksAsync(boolean sendAcksAsync) {
this.sendAcksAsync = sendAcksAsync;
}
-
+
/**
* @return the messagePrioritySupported
*/
@@ -617,6 +637,7 @@ public class ActiveMQConnectionFactory extends JNDIBaseStorable implements Conne
this.transformer = transformer;
}
+ @SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public void buildFromProperties(Properties properties) {
@@ -751,7 +772,7 @@ public class ActiveMQConnectionFactory extends JNDIBaseStorable implements Conne
* minimize context switches which boost performance. However sometimes its
* better to go slower to ensure that a single blocked consumer socket does
* not block delivery to other consumers.
- *
+ *
* @param asyncDispatch If true then consumers created on this connection
* will default to having their messages dispatched
* asynchronously. The default value is false.
@@ -841,7 +862,7 @@ public class ActiveMQConnectionFactory extends JNDIBaseStorable implements Conne
/**
* Sets the prefix used by autogenerated JMS Client ID values which are used
* if the JMS client does not explicitly specify on.
- *
+ *
* @param clientIDPrefix
*/
public void setClientIDPrefix(String clientIDPrefix) {
@@ -941,12 +962,12 @@ public class ActiveMQConnectionFactory extends JNDIBaseStorable implements Conne
public void setTransportListener(TransportListener transportListener) {
this.transportListener = transportListener;
}
-
-
+
+
public ExceptionListener getExceptionListener() {
return exceptionListener;
}
-
+
/**
* Allows an {@link ExceptionListener} to be configured on the ConnectionFactory so that when this factory
* is used by frameworks which don't expose the Connection such as Spring JmsTemplate, you can register
@@ -957,37 +978,37 @@ public class ActiveMQConnectionFactory extends JNDIBaseStorable implements Conne
* created by this factory
*/
public void setExceptionListener(ExceptionListener exceptionListener) {
- this.exceptionListener = exceptionListener;
+ this.exceptionListener = exceptionListener;
}
- public int getAuditDepth() {
- return auditDepth;
- }
+ public int getAuditDepth() {
+ return auditDepth;
+ }
- public void setAuditDepth(int auditDepth) {
- this.auditDepth = auditDepth;
- }
+ public void setAuditDepth(int auditDepth) {
+ this.auditDepth = auditDepth;
+ }
- public int getAuditMaximumProducerNumber() {
- return auditMaximumProducerNumber;
- }
+ public int getAuditMaximumProducerNumber() {
+ return auditMaximumProducerNumber;
+ }
- public void setAuditMaximumProducerNumber(int auditMaximumProducerNumber) {
- this.auditMaximumProducerNumber = auditMaximumProducerNumber;
- }
+ public void setAuditMaximumProducerNumber(int auditMaximumProducerNumber) {
+ this.auditMaximumProducerNumber = auditMaximumProducerNumber;
+ }
public void setUseDedicatedTaskRunner(boolean useDedicatedTaskRunner) {
this.useDedicatedTaskRunner = useDedicatedTaskRunner;
}
-
+
public boolean isUseDedicatedTaskRunner() {
return useDedicatedTaskRunner;
}
-
+
public void setConsumerFailoverRedeliveryWaitPeriod(long consumerFailoverRedeliveryWaitPeriod) {
this.consumerFailoverRedeliveryWaitPeriod = consumerFailoverRedeliveryWaitPeriod;
}
-
+
public long getConsumerFailoverRedeliveryWaitPeriod() {
return consumerFailoverRedeliveryWaitPeriod;
}
@@ -995,7 +1016,7 @@ public class ActiveMQConnectionFactory extends JNDIBaseStorable implements Conne
public ClientInternalExceptionListener getClientInternalExceptionListener() {
return clientInternalExceptionListener;
}
-
+
/**
* Allows an {@link ClientInternalExceptionListener} to be configured on the ConnectionFactory so that when this factory
* is used by frameworks which don't expose the Connection such as Spring JmsTemplate, you can register
diff --git a/activemq-core/src/main/java/org/apache/activemq/broker/DefaultBrokerFactory.java b/activemq-core/src/main/java/org/apache/activemq/broker/DefaultBrokerFactory.java
index 656577f308..e31d0d193f 100644
--- a/activemq-core/src/main/java/org/apache/activemq/broker/DefaultBrokerFactory.java
+++ b/activemq-core/src/main/java/org/apache/activemq/broker/DefaultBrokerFactory.java
@@ -28,8 +28,8 @@ import org.apache.activemq.util.URISupport.CompositeData;
* Simple BrokerFactorySPI which using the brokerURI to extract the
* configuration parameters for the broker service. This directly configures the
* pojo model so there is no dependency on spring for configuration.
- *
- *
+ *
+ *
*/
public class DefaultBrokerFactory implements BrokerFactoryHandler {
@@ -40,6 +40,15 @@ public class DefaultBrokerFactory implements BrokerFactoryHandler {
BrokerService brokerService = new BrokerService();
IntrospectionSupport.setProperties(brokerService, params);
+ if (!params.isEmpty()) {
+ String msg = "There are " + params.size()
+ + " Broker options that couldn't be set on the BrokerService."
+ + " Check the options are spelled correctly."
+ + " Unknown parameters=[" + params + "]."
+ + " This BrokerService cannot be started.";
+ throw new IllegalArgumentException(msg);
+ }
+
if (compositeData.getPath() != null) {
brokerService.setBrokerName(compositeData.getPath());
}
diff --git a/activemq-core/src/main/java/org/apache/activemq/util/URISupport.java b/activemq-core/src/main/java/org/apache/activemq/util/URISupport.java
index 686f8f3054..e969fc0db5 100755
--- a/activemq-core/src/main/java/org/apache/activemq/util/URISupport.java
+++ b/activemq-core/src/main/java/org/apache/activemq/util/URISupport.java
@@ -24,12 +24,11 @@ import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
- *
+ * Utility class that provides methods for parsing URI's
*/
public class URISupport {
@@ -105,7 +104,7 @@ public class URISupport {
try {
uri = uri.substring(uri.lastIndexOf("?") + 1); // get only the relevant part of the query
Map rc = new HashMap();
- if (uri != null) {
+ if (uri != null && !uri.isEmpty()) {
String[] parameters = uri.split("&");
for (int i = 0; i < parameters.length; i++) {
int p = parameters[i].indexOf("=");
@@ -134,7 +133,7 @@ public class URISupport {
if (parameters.isEmpty()) {
parameters = emptyMap();
}
-
+
return parameters;
}
}
@@ -159,7 +158,7 @@ public class URISupport {
}
return uri;
}
-
+
@SuppressWarnings("unchecked")
private static Map emptyMap() {
return Collections.EMPTY_MAP;
@@ -181,7 +180,7 @@ public class URISupport {
int questionMark = schemeSpecificPart.lastIndexOf("?");
// make sure question mark is not within parentheses
if (questionMark < schemeSpecificPart.lastIndexOf(")")) {
- questionMark = -1;
+ questionMark = -1;
}
if (questionMark > 0) {
schemeSpecificPart = schemeSpecificPart.substring(0, questionMark);
@@ -197,14 +196,14 @@ public class URISupport {
CompositeData rc = new CompositeData();
rc.scheme = uri.getScheme();
String ssp = stripPrefix(uri.getRawSchemeSpecificPart().trim(), "//").trim();
-
+
parseComposite(uri, rc, ssp);
rc.fragment = uri.getFragment();
return rc;
}
-
+
public static boolean isCompositeURI(URI uri) {
if (uri.getQuery() != null) {
return false;
@@ -322,18 +321,17 @@ public class URISupport {
return new URI(stripPrefix(uri.getSchemeSpecificPart().trim(), "//"));
}
- public static String createQueryString(Map options) throws URISyntaxException {
+ public static String createQueryString(Map options) throws URISyntaxException {
try {
if (options.size() > 0) {
StringBuffer rc = new StringBuffer();
boolean first = true;
- for (Iterator iter = options.keySet().iterator(); iter.hasNext();) {
+ for (String key : options.keySet()) {
if (first) {
first = false;
} else {
rc.append("&");
}
- String key = (String)iter.next();
String value = (String)options.get(key);
rc.append(URLEncoder.encode(key, "UTF-8"));
rc.append("=");
@@ -350,10 +348,10 @@ public class URISupport {
/**
* Creates a URI from the original URI and the remaining paramaters
- *
+ *
* @throws URISyntaxException
*/
- public static URI createRemainingURI(URI originalURI, Map params) throws URISyntaxException {
+ public static URI createRemainingURI(URI originalURI, Map params) throws URISyntaxException {
String s = createQueryString(params);
if (s.length() == 0) {
s = null;