activemq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From martyntay...@apache.org
Subject [5/5] activemq-artemis git commit: ARTEMIS-604 - Message Serialization Improvement - JMS and RA fixes
Date Tue, 09 Aug 2016 10:23:08 GMT
ARTEMIS-604 - Message Serialization Improvement
  - JMS and RA fixes


Project: http://git-wip-us.apache.org/repos/asf/activemq-artemis/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-artemis/commit/0535218c
Tree: http://git-wip-us.apache.org/repos/asf/activemq-artemis/tree/0535218c
Diff: http://git-wip-us.apache.org/repos/asf/activemq-artemis/diff/0535218c

Branch: refs/heads/master
Commit: 0535218cfcabfe521286f35c3471eeb3c9bb41dc
Parents: d88ede9
Author: Howard Gao <howard.gao@gmail.com>
Authored: Mon Aug 1 09:59:59 2016 +0800
Committer: Martyn Taylor <mtaylor@redhat.com>
Committed: Tue Aug 9 11:22:48 2016 +0100

----------------------------------------------------------------------
 .../utils/ObjectInputStreamWithClassLoader.java | 142 ++++++-
 .../activemq/artemis/utils/StringUtil.java      |  58 +++
 .../activemq/artemis/util/StringUtilTest.java   |  56 +++
 .../artemis/jms/client/ActiveMQConnection.java  |  19 +-
 .../jms/client/ActiveMQConnectionFactory.java   |  34 +-
 .../artemis/jms/client/ActiveMQMessage.java     |   7 +-
 .../jms/client/ActiveMQMessageConsumer.java     |  17 +-
 .../jms/client/ActiveMQMessageProducer.java     |   8 +-
 .../jms/client/ActiveMQObjectMessage.java       |  40 +-
 .../jms/client/ActiveMQQueueBrowser.java        |   8 +-
 .../artemis/jms/client/ActiveMQSession.java     |  27 +-
 .../jms/client/ActiveMQXAConnection.java        |   5 +-
 .../artemis/jms/client/ActiveMQXASession.java   |   5 +-
 .../jms/client/ConnectionFactoryOptions.java    |  33 ++
 .../jms/client/JMSMessageListenerWrapper.java   |   8 +-
 .../config/ConnectionFactoryConfiguration.java  |   8 +
 .../ConnectionFactoryConfigurationImpl.java     |  38 +-
 .../artemis/ra/ActiveMQResourceAdapter.java     |  38 ++
 .../artemis/ra/ConnectionFactoryProperties.java |  46 ++-
 .../artemis/ra/inflow/ActiveMQActivation.java   |   2 +-
 .../ra/inflow/ActiveMQMessageHandler.java       |   9 +-
 docs/user-manual/en/security.md                 |  74 ++++
 .../jms/ActiveMQConnectionFactoryTest.java      | 223 +++++++++++
 .../jms/serializables/TestClass1.java           |  22 ++
 .../ra/ActiveMQMessageHandlerTest.java          | 108 ++++++
 .../jms/tests/message/MessageHeaderTest.java    |   2 +-
 .../ra/ActiveMQResourceAdapterConfigTest.java   |  12 +
 .../tests/unit/ra/ResourceAdapterTest.java      |  37 ++
 .../ObjectInputStreamWithClassLoaderTest.java   | 383 ++++++++++++++++++-
 .../deserialization/pkg1/EnclosingClass.java    |  31 ++
 .../util/deserialization/pkg1/TestClass1.java   |  22 ++
 .../util/deserialization/pkg1/TestClass2.java   |  22 ++
 32 files changed, 1483 insertions(+), 61 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/0535218c/artemis-core-client/src/main/java/org/apache/activemq/artemis/utils/ObjectInputStreamWithClassLoader.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/utils/ObjectInputStreamWithClassLoader.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/utils/ObjectInputStreamWithClassLoader.java
index ddc3564..6aa0f50 100644
--- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/utils/ObjectInputStreamWithClassLoader.java
+++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/utils/ObjectInputStreamWithClassLoader.java
@@ -25,23 +25,79 @@ import java.lang.reflect.Proxy;
 import java.security.AccessController;
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
+import java.util.ArrayList;
+import java.util.List;
 
 public class ObjectInputStreamWithClassLoader extends ObjectInputStream {
 
    // Constants ------------------------------------------------------------------------------------
 
+   /**
+    * Value used to indicate that all classes should be white or black listed,
+    */
+   public static final String CATCH_ALL_WILDCARD = "*";
+
+   public static final String WHITELIST_PROPERTY = "org.apache.activemq.artemis.jms.deserialization.whitelist";
+   public static final String BLACKLIST_PROPERTY = "org.apache.activemq.artemis.jms.deserialization.blacklist";
+
    // Attributes -----------------------------------------------------------------------------------
 
+   private List<String> whiteList = new ArrayList<>();
+   private List<String> blackList = new ArrayList<>();
+
    // Static ---------------------------------------------------------------------------------------
 
    // Constructors ---------------------------------------------------------------------------------
 
    public ObjectInputStreamWithClassLoader(final InputStream in) throws IOException {
       super(in);
+      String whiteList = System.getProperty(WHITELIST_PROPERTY, null);
+      setWhiteList(whiteList);
+
+      String blackList = System.getProperty(BLACKLIST_PROPERTY, null);
+      setBlackList(blackList);
    }
 
    // Public ---------------------------------------------------------------------------------------
 
+   /**
+    * @return the whiteList configured on this policy instance.
+    */
+   public String getWhiteList() {
+      return StringUtil.joinStringList(whiteList, ",");
+   }
+
+   /**
+    * @return the blackList configured on this policy instance.
+    */
+   public String getBlackList() {
+      return StringUtil.joinStringList(blackList, ",");
+   }
+
+   /**
+    * Replaces the currently configured whiteList with a comma separated
+    * string containing the new whiteList. Null or empty string denotes
+    * no whiteList entries, {@value #CATCH_ALL_WILDCARD} indicates that
+    * all classes are whiteListed.
+    *
+    * @param whiteList the whiteList that this policy is configured to recognize.
+    */
+   public void setWhiteList(String whiteList) {
+      this.whiteList = StringUtil.splitStringList(whiteList, ",");
+   }
+
+   /**
+    * Replaces the currently configured blackList with a comma separated
+    * string containing the new blackList. Null or empty string denotes
+    * no blacklist entries, {@value #CATCH_ALL_WILDCARD} indicates that
+    * all classes are blacklisted.
+    *
+    * @param blackList the blackList that this policy is configured to recognize.
+    */
+   public void setBlackList(String blackList) {
+      this.blackList = StringUtil.splitStringList(blackList, ",");
+   }
+
    // Package protected ----------------------------------------------------------------------------
 
    // Protected ------------------------------------------------------------------------------------
@@ -97,14 +153,13 @@ public class ObjectInputStreamWithClassLoader extends ObjectInputStream {
          Class clazz = Class.forName(name, false, loader);
          // sanity check only.. if a classLoader can't find a clazz, it will throw an exception
          if (clazz == null) {
-            return super.resolveClass(desc);
-         }
-         else {
-            return clazz;
+            clazz = super.resolveClass(desc);
          }
+
+         return checkSecurity(clazz);
       }
       catch (ClassNotFoundException e) {
-         return super.resolveClass(desc);
+         return checkSecurity(super.resolveClass(desc));
       }
    }
 
@@ -130,7 +185,7 @@ public class ObjectInputStreamWithClassLoader extends ObjectInputStream {
          classObjs[i] = cl;
       }
       try {
-         return Proxy.getProxyClass(hasNonPublicInterface ? nonPublicLoader : latestLoader, classObjs);
+         return checkSecurity(Proxy.getProxyClass(hasNonPublicInterface ? nonPublicLoader : latestLoader, classObjs));
       }
       catch (IllegalArgumentException e) {
          throw new ClassNotFoundException(null, e);
@@ -156,6 +211,81 @@ public class ObjectInputStreamWithClassLoader extends ObjectInputStream {
       }
    }
 
+   private Class<?> checkSecurity(Class<?> clazz) throws ClassNotFoundException {
+      Class<?> target = clazz;
+
+      while (target.isArray()) {
+         target = target.getComponentType();
+      }
+
+      while (target.isAnonymousClass() || target.isLocalClass()) {
+         target = target.getEnclosingClass();
+      }
+
+      if (!target.isPrimitive()) {
+         if (!isTrustedType(target)) {
+            throw new ClassNotFoundException("Forbidden " + clazz + "! " +
+                    "This class is not trusted to be deserialized under the current configuration. " +
+                    "Please refer to the documentation for more information on how to configure trusted classes.");
+         }
+      }
+
+      return clazz;
+   }
+
+   private boolean isTrustedType(Class<?> clazz) {
+      if (clazz == null) {
+         return true;
+      }
+
+      String className = clazz.getCanonicalName();
+      if (className == null) {
+         // Shouldn't happen as we pre-processed things, but just in case..
+         className = clazz.getName();
+      }
+
+      for (String blackListEntry : blackList) {
+         if (CATCH_ALL_WILDCARD.equals(blackListEntry)) {
+            return false;
+         }
+         else if (isClassOrPackageMatch(className, blackListEntry)) {
+            return false;
+         }
+      }
+
+      for (String whiteListEntry : whiteList) {
+         if (CATCH_ALL_WILDCARD.equals(whiteListEntry)) {
+            return true;
+         }
+         else if (isClassOrPackageMatch(className, whiteListEntry)) {
+            return true;
+         }
+      }
+
+      // Failing outright rejection or allow from above
+      // reject only if the whiteList is not empty.
+      return whiteList.size() == 0;
+   }
+
+   private boolean isClassOrPackageMatch(String className, String listEntry) {
+      if (className == null) {
+         return false;
+      }
+
+      // Check if class is an exact match of the entry
+      if (className.equals(listEntry)) {
+         return true;
+      }
+
+      // Check if class is from a [sub-]package matching the entry
+      int entryLength = listEntry.length();
+      if (className.length() > entryLength && className.startsWith(listEntry) && '.' == className.charAt(entryLength)) {
+         return true;
+      }
+
+      return false;
+   }
+
    // Inner classes --------------------------------------------------------------------------------
 
 }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/0535218c/artemis-core-client/src/main/java/org/apache/activemq/artemis/utils/StringUtil.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/utils/StringUtil.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/utils/StringUtil.java
new file mode 100644
index 0000000..1b40209
--- /dev/null
+++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/utils/StringUtil.java
@@ -0,0 +1,58 @@
+/*
+ * 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.artemis.utils;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+public class StringUtil {
+
+   /**
+    * Convert a list of Strings into a single String
+    * @param strList the string list
+    * @param delimit the delimiter used to separate each string entry in the list
+    * @return the converted string
+    */
+   public static String joinStringList(List<String> strList, String delimit) {
+      Iterator<String> entries = strList.iterator();
+      StringBuilder builder = new StringBuilder();
+
+      while (entries.hasNext()) {
+         builder.append(entries.next());
+         if (entries.hasNext()) {
+            builder.append(delimit);
+         }
+      }
+      return builder.toString();
+   }
+
+   /**
+    * Convert a String into a list of String
+    * @param strList the String
+    * @param delimit used to separate items within the string.
+    * @return the string list
+    */
+   public static List<String> splitStringList(String strList, String delimit) {
+      ArrayList<String> list = new ArrayList<>();
+      if (strList != null && !strList.isEmpty()) {
+         list.addAll(Arrays.asList(strList.split(delimit)));
+      }
+      return list;
+   }
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/0535218c/artemis-core-client/src/test/java/org/apache/activemq/artemis/util/StringUtilTest.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/test/java/org/apache/activemq/artemis/util/StringUtilTest.java b/artemis-core-client/src/test/java/org/apache/activemq/artemis/util/StringUtilTest.java
new file mode 100644
index 0000000..76f3ec1
--- /dev/null
+++ b/artemis-core-client/src/test/java/org/apache/activemq/artemis/util/StringUtilTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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.artemis.util;
+
+import org.apache.activemq.artemis.utils.StringUtil;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class StringUtilTest extends Assert {
+
+   @Test
+   public void testJoinStringList() throws Exception {
+      List<String> strList = new ArrayList<>();
+      strList.add("a");
+      strList.add("bc");
+      strList.add("def");
+      String result = StringUtil.joinStringList(strList, ",");
+      assertEquals("a,bc,def", result);
+
+      List<String> newList = StringUtil.splitStringList(result, ",");
+      assertEquals(strList.size(), newList.size());
+      String result2 = StringUtil.joinStringList(newList, ",");
+      assertEquals(result, result2);
+   }
+
+   @Test
+   public void testSplitStringList() throws Exception {
+      String listStr = "white,blue,yellow,green";
+      List<String> result = StringUtil.splitStringList(listStr, ",");
+      assertEquals(4, result.size());
+      assertEquals("white", result.get(0));
+      assertEquals("blue", result.get(1));
+      assertEquals("yellow", result.get(2));
+      assertEquals("green", result.get(3));
+
+      String result2 = StringUtil.joinStringList(result, ",");
+      assertEquals(listStr, result2);
+   }
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/0535218c/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQConnection.java
----------------------------------------------------------------------
diff --git a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQConnection.java b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQConnection.java
index 80597e3..fc9c59d 100644
--- a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQConnection.java
+++ b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQConnection.java
@@ -130,15 +130,20 @@ public class ActiveMQConnection extends ActiveMQConnectionForContextImpl impleme
 
    private ActiveMQConnectionFactory factoryReference;
 
+   private final ConnectionFactoryOptions options;
+
    // Constructors ---------------------------------------------------------------------------------
 
-   public ActiveMQConnection(final String username,
+   public ActiveMQConnection(final ConnectionFactoryOptions options,
+                             final String username,
                              final String password,
                              final int connectionType,
                              final String clientID,
                              final int dupsOKBatchSize,
                              final int transactionBatchSize,
                              final ClientSessionFactory sessionFactory) {
+      this.options = options;
+
       this.username = username;
 
       this.password = password;
@@ -651,10 +656,10 @@ public class ActiveMQConnection extends ActiveMQConnectionForContextImpl impleme
                                               ClientSession session,
                                               int type) {
       if (isXA) {
-         return new ActiveMQXASession(this, transacted, true, acknowledgeMode, session, type);
+         return new ActiveMQXASession(options, this, transacted, true, acknowledgeMode, session, type);
       }
       else {
-         return new ActiveMQSession(this, transacted, false, acknowledgeMode, session, type);
+         return new ActiveMQSession(options, this, transacted, false, acknowledgeMode, session, type);
       }
    }
 
@@ -693,6 +698,14 @@ public class ActiveMQConnection extends ActiveMQConnectionForContextImpl impleme
       return started;
    }
 
+   public String getDeserializationBlackList() {
+      return this.factoryReference.getDeserializationBlackList();
+   }
+
+   public String getDeserializationWhiteList() {
+      return this.factoryReference.getDeserializationWhiteList();
+   }
+
    // Inner classes --------------------------------------------------------------------------------
 
    private static class JMSFailureListener implements SessionFailureListener {

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/0535218c/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQConnectionFactory.java
----------------------------------------------------------------------
diff --git a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQConnectionFactory.java b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQConnectionFactory.java
index ce2aa3a..183745d 100644
--- a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQConnectionFactory.java
+++ b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQConnectionFactory.java
@@ -61,7 +61,7 @@ import org.apache.activemq.artemis.utils.ClassloadingUtil;
  * <p>ActiveMQ Artemis implementation of a JMS ConnectionFactory.</p>
  * <p>This connection factory will use defaults defined by {@link DefaultConnectionProperties}.
  */
-public class ActiveMQConnectionFactory implements Externalizable, Referenceable, ConnectionFactory, XAConnectionFactory, AutoCloseable {
+public class ActiveMQConnectionFactory implements ConnectionFactoryOptions, Externalizable, Referenceable, ConnectionFactory, XAConnectionFactory, AutoCloseable {
 
    private ServerLocator serverLocator;
 
@@ -79,6 +79,10 @@ public class ActiveMQConnectionFactory implements Externalizable, Referenceable,
 
    private String protocolManagerFactoryStr;
 
+   private String deserializationBlackList;
+
+   private String deserializationWhiteList;
+
    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
       URI uri = toURI();
@@ -150,6 +154,22 @@ public class ActiveMQConnectionFactory implements Externalizable, Referenceable,
       }
    }
 
+   public String getDeserializationBlackList() {
+      return deserializationBlackList;
+   }
+
+   public void setDeserializationBlackList(String blackList) {
+      this.deserializationBlackList = blackList;
+   }
+
+   public String getDeserializationWhiteList() {
+      return deserializationWhiteList;
+   }
+
+   public void setDeserializationWhiteList(String whiteList) {
+      this.deserializationWhiteList = whiteList;
+   }
+
    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
       String url = in.readUTF();
@@ -744,24 +764,24 @@ public class ActiveMQConnectionFactory implements Externalizable, Referenceable,
 
       if (isXA) {
          if (type == ActiveMQConnection.TYPE_GENERIC_CONNECTION) {
-            connection = new ActiveMQXAConnection(username, password, type, clientID, dupsOKBatchSize, transactionBatchSize, factory);
+            connection = new ActiveMQXAConnection(this, username, password, type, clientID, dupsOKBatchSize, transactionBatchSize, factory);
          }
          else if (type == ActiveMQConnection.TYPE_QUEUE_CONNECTION) {
-            connection = new ActiveMQXAConnection(username, password, type, clientID, dupsOKBatchSize, transactionBatchSize, factory);
+            connection = new ActiveMQXAConnection(this, username, password, type, clientID, dupsOKBatchSize, transactionBatchSize, factory);
          }
          else if (type == ActiveMQConnection.TYPE_TOPIC_CONNECTION) {
-            connection = new ActiveMQXAConnection(username, password, type, clientID, dupsOKBatchSize, transactionBatchSize, factory);
+            connection = new ActiveMQXAConnection(this, username, password, type, clientID, dupsOKBatchSize, transactionBatchSize, factory);
          }
       }
       else {
          if (type == ActiveMQConnection.TYPE_GENERIC_CONNECTION) {
-            connection = new ActiveMQConnection(username, password, type, clientID, dupsOKBatchSize, transactionBatchSize, factory);
+            connection = new ActiveMQConnection(this, username, password, type, clientID, dupsOKBatchSize, transactionBatchSize, factory);
          }
          else if (type == ActiveMQConnection.TYPE_QUEUE_CONNECTION) {
-            connection = new ActiveMQConnection(username, password, type, clientID, dupsOKBatchSize, transactionBatchSize, factory);
+            connection = new ActiveMQConnection(this, username, password, type, clientID, dupsOKBatchSize, transactionBatchSize, factory);
          }
          else if (type == ActiveMQConnection.TYPE_TOPIC_CONNECTION) {
-            connection = new ActiveMQConnection(username, password, type, clientID, dupsOKBatchSize, transactionBatchSize, factory);
+            connection = new ActiveMQConnection(this, username, password, type, clientID, dupsOKBatchSize, transactionBatchSize, factory);
          }
       }
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/0535218c/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQMessage.java
----------------------------------------------------------------------
diff --git a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQMessage.java b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQMessage.java
index 2dd0df1..ab9e311 100644
--- a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQMessage.java
+++ b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQMessage.java
@@ -121,6 +121,10 @@ public class ActiveMQMessage implements javax.jms.Message {
    }
 
    public static ActiveMQMessage createMessage(final ClientMessage message, final ClientSession session) {
+      return createMessage(message, session, null);
+   }
+
+   public static ActiveMQMessage createMessage(final ClientMessage message, final ClientSession session, final ConnectionFactoryOptions options) {
       int type = message.getType();
 
       ActiveMQMessage msg;
@@ -142,7 +146,7 @@ public class ActiveMQMessage implements javax.jms.Message {
             break;
          }
          case ActiveMQObjectMessage.TYPE: {
-            msg = new ActiveMQObjectMessage(message, session);
+            msg = new ActiveMQObjectMessage(message, session, options);
             break;
          }
          case ActiveMQStreamMessage.TYPE: // 6
@@ -202,7 +206,6 @@ public class ActiveMQMessage implements javax.jms.Message {
     */
    protected ActiveMQMessage(final byte type, final ClientSession session) {
       message = session.createMessage(type, true, 0, System.currentTimeMillis(), (byte) 4);
-
    }
 
    protected ActiveMQMessage(final ClientSession session) {

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/0535218c/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQMessageConsumer.java
----------------------------------------------------------------------
diff --git a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQMessageConsumer.java b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQMessageConsumer.java
index 53242f1..5fbf448 100644
--- a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQMessageConsumer.java
+++ b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQMessageConsumer.java
@@ -31,6 +31,7 @@ import org.apache.activemq.artemis.api.core.ActiveMQInterruptedException;
 import org.apache.activemq.artemis.api.core.SimpleString;
 import org.apache.activemq.artemis.api.core.client.ClientConsumer;
 import org.apache.activemq.artemis.api.core.client.ClientMessage;
+import org.apache.activemq.artemis.api.core.client.ClientSession;
 import org.apache.activemq.artemis.api.core.client.MessageHandler;
 import org.apache.activemq.artemis.api.jms.ActiveMQJMSConstants;
 import org.apache.activemq.artemis.core.client.ActiveMQClientLogger;
@@ -41,6 +42,8 @@ import org.apache.activemq.artemis.core.client.impl.ClientSessionInternal;
  */
 public final class ActiveMQMessageConsumer implements QueueReceiver, TopicSubscriber {
 
+   private final ConnectionFactoryOptions options;
+
    private final ClientConsumer consumer;
 
    private MessageListener listener;
@@ -63,13 +66,16 @@ public final class ActiveMQMessageConsumer implements QueueReceiver, TopicSubscr
 
    // Constructors --------------------------------------------------
 
-   protected ActiveMQMessageConsumer(final ActiveMQConnection connection,
+   protected ActiveMQMessageConsumer(final ConnectionFactoryOptions options,
+                                     final ActiveMQConnection connection,
                                      final ActiveMQSession session,
                                      final ClientConsumer consumer,
                                      final boolean noLocal,
                                      final ActiveMQDestination destination,
                                      final String selector,
                                      final SimpleString autoDeleteQueueName) throws JMSException {
+      this.options = options;
+
       this.connection = connection;
 
       this.session = session;
@@ -107,7 +113,7 @@ public final class ActiveMQMessageConsumer implements QueueReceiver, TopicSubscr
    public void setMessageListener(final MessageListener listener) throws JMSException {
       this.listener = listener;
 
-      coreListener = listener == null ? null : new JMSMessageListenerWrapper(connection, session, consumer, listener, ackMode);
+      coreListener = listener == null ? null : new JMSMessageListenerWrapper(options, connection, session, consumer, listener, ackMode);
 
       try {
          consumer.setMessageHandler(coreListener);
@@ -211,8 +217,11 @@ public final class ActiveMQMessageConsumer implements QueueReceiver, TopicSubscr
          ActiveMQMessage jmsMsg = null;
 
          if (coreMessage != null) {
-            boolean needSession = ackMode == Session.CLIENT_ACKNOWLEDGE || ackMode == ActiveMQJMSConstants.INDIVIDUAL_ACKNOWLEDGE;
-            jmsMsg = ActiveMQMessage.createMessage(coreMessage, needSession ? session.getCoreSession() : null);
+            ClientSession coreSession = session.getCoreSession();
+            boolean needSession = ackMode == Session.CLIENT_ACKNOWLEDGE ||
+                                             ackMode == ActiveMQJMSConstants.INDIVIDUAL_ACKNOWLEDGE ||
+                                             coreMessage.getType() == ActiveMQObjectMessage.TYPE;
+            jmsMsg = ActiveMQMessage.createMessage(coreMessage, needSession ? coreSession : null, options);
 
             try {
                jmsMsg.doBeforeReceive();

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/0535218c/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQMessageProducer.java
----------------------------------------------------------------------
diff --git a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQMessageProducer.java b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQMessageProducer.java
index 5a0d5c3..8a47e8c 100644
--- a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQMessageProducer.java
+++ b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQMessageProducer.java
@@ -49,6 +49,8 @@ import org.apache.activemq.artemis.utils.UUIDGenerator;
  */
 public class ActiveMQMessageProducer implements MessageProducer, QueueSender, TopicPublisher {
 
+   private final ConnectionFactoryOptions options;
+
    private final ActiveMQConnection connection;
 
    private final SimpleString connID;
@@ -71,7 +73,9 @@ public class ActiveMQMessageProducer implements MessageProducer, QueueSender, To
    protected ActiveMQMessageProducer(final ActiveMQConnection connection,
                                      final ClientProducer producer,
                                      final ActiveMQDestination defaultDestination,
-                                     final ClientSession clientSession) throws JMSException {
+                                     final ClientSession clientSession,
+                                     final ConnectionFactoryOptions options) throws JMSException {
+      this.options = options;
       this.connection = connection;
 
       connID = connection.getClientID() != null ? new SimpleString(connection.getClientID()) : connection.getUID();
@@ -434,7 +438,7 @@ public class ActiveMQMessageProducer implements MessageProducer, QueueSender, To
             activeMQJmsMessage = new ActiveMQMapMessage((MapMessage) jmsMessage, clientSession);
          }
          else if (jmsMessage instanceof ObjectMessage) {
-            activeMQJmsMessage = new ActiveMQObjectMessage((ObjectMessage) jmsMessage, clientSession);
+            activeMQJmsMessage = new ActiveMQObjectMessage((ObjectMessage) jmsMessage, clientSession, options);
          }
          else if (jmsMessage instanceof StreamMessage) {
             activeMQJmsMessage = new ActiveMQStreamMessage((StreamMessage) jmsMessage, clientSession);

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/0535218c/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQObjectMessage.java
----------------------------------------------------------------------
diff --git a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQObjectMessage.java b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQObjectMessage.java
index c8b1213..0e6bbda 100644
--- a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQObjectMessage.java
+++ b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQObjectMessage.java
@@ -21,7 +21,6 @@ import javax.jms.MessageFormatException;
 import javax.jms.ObjectMessage;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
-import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.io.Serializable;
 
@@ -48,25 +47,30 @@ public class ActiveMQObjectMessage extends ActiveMQMessage implements ObjectMess
    // keep a snapshot of the Serializable Object as a byte[] to provide Object isolation
    private byte[] data;
 
+   private final ConnectionFactoryOptions options;
+
    // Static --------------------------------------------------------
 
    // Constructors --------------------------------------------------
 
-   protected ActiveMQObjectMessage(final ClientSession session) {
+   protected ActiveMQObjectMessage(final ClientSession session, ConnectionFactoryOptions options) {
       super(ActiveMQObjectMessage.TYPE, session);
+      this.options = options;
    }
 
-   protected ActiveMQObjectMessage(final ClientMessage message, final ClientSession session) {
+   protected ActiveMQObjectMessage(final ClientMessage message, final ClientSession session, ConnectionFactoryOptions options) {
       super(message, session);
+      this.options = options;
    }
 
    /**
     * A copy constructor for foreign JMS ObjectMessages.
     */
-   public ActiveMQObjectMessage(final ObjectMessage foreign, final ClientSession session) throws JMSException {
+   public ActiveMQObjectMessage(final ObjectMessage foreign, final ClientSession session, ConnectionFactoryOptions options) throws JMSException {
       super(foreign, ActiveMQObjectMessage.TYPE, session);
 
       setObject(foreign.getObject());
+      this.options = options;
    }
 
    // Public --------------------------------------------------------
@@ -135,7 +139,15 @@ public class ActiveMQObjectMessage extends ActiveMQMessage implements ObjectMess
          return null;
       }
 
-      try (ObjectInputStream ois = new ObjectInputStreamWithClassLoader(new ByteArrayInputStream(data))) {
+      try (ObjectInputStreamWithClassLoader ois = new ObjectInputStreamWithClassLoader(new ByteArrayInputStream(data))) {
+         String blackList = getDeserializationBlackList();
+         if (blackList != null) {
+            ois.setBlackList(blackList);
+         }
+         String whiteList = getDeserializationWhiteList();
+         if (whiteList != null) {
+            ois.setWhiteList(whiteList);
+         }
          Serializable object = (Serializable) ois.readObject();
          return object;
       }
@@ -174,4 +186,22 @@ public class ActiveMQObjectMessage extends ActiveMQMessage implements ObjectMess
          return false;
       }
    }
+
+   private String getDeserializationBlackList() {
+      if (options == null) {
+         return null;
+      }
+      else {
+         return options.getDeserializationBlackList();
+      }
+   }
+
+   private String getDeserializationWhiteList() {
+      if (options == null) {
+         return null;
+      }
+      else {
+         return options.getDeserializationWhiteList();
+      }
+   }
 }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/0535218c/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQQueueBrowser.java
----------------------------------------------------------------------
diff --git a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQQueueBrowser.java b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQQueueBrowser.java
index 231a681..adb2219 100644
--- a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQQueueBrowser.java
+++ b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQQueueBrowser.java
@@ -40,6 +40,8 @@ public final class ActiveMQQueueBrowser implements QueueBrowser {
 
    // Attributes -----------------------------------------------------------------------------------
 
+   private final ConnectionFactoryOptions options;
+
    private final ClientSession session;
 
    private ClientConsumer consumer;
@@ -50,9 +52,11 @@ public final class ActiveMQQueueBrowser implements QueueBrowser {
 
    // Constructors ---------------------------------------------------------------------------------
 
-   protected ActiveMQQueueBrowser(final ActiveMQQueue queue,
+   protected ActiveMQQueueBrowser(final ConnectionFactoryOptions options,
+                                  final ActiveMQQueue queue,
                                   final String messageSelector,
                                   final ClientSession session) throws JMSException {
+      this.options = options;
       this.session = session;
       this.queue = queue;
       if (messageSelector != null) {
@@ -137,7 +141,7 @@ public final class ActiveMQQueueBrowser implements QueueBrowser {
          if (hasMoreElements()) {
             ClientMessage next = current;
             current = null;
-            msg = ActiveMQMessage.createMessage(next, session);
+            msg = ActiveMQMessage.createMessage(next, session, options);
             try {
                msg.doBeforeReceive();
             }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/0535218c/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQSession.java
----------------------------------------------------------------------
diff --git a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQSession.java b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQSession.java
index ee81cf1..3ba2945 100644
--- a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQSession.java
+++ b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQSession.java
@@ -77,6 +77,8 @@ public class ActiveMQSession implements QueueSession, TopicSession {
 
    private static SimpleString REJECTING_FILTER = new SimpleString("_AMQX=-1");
 
+   private final ConnectionFactoryOptions options;
+
    private final ActiveMQConnection connection;
 
    private final ClientSession session;
@@ -95,12 +97,15 @@ public class ActiveMQSession implements QueueSession, TopicSession {
 
    // Constructors --------------------------------------------------
 
-   protected ActiveMQSession(final ActiveMQConnection connection,
+   protected ActiveMQSession(final ConnectionFactoryOptions options,
+                             final ActiveMQConnection connection,
                              final boolean transacted,
                              final boolean xa,
                              final int ackMode,
                              final ClientSession session,
                              final int sessionType) {
+      this.options = options;
+
       this.connection = connection;
 
       this.ackMode = ackMode;
@@ -141,14 +146,14 @@ public class ActiveMQSession implements QueueSession, TopicSession {
    public ObjectMessage createObjectMessage() throws JMSException {
       checkClosed();
 
-      return new ActiveMQObjectMessage(session);
+      return new ActiveMQObjectMessage(session, options);
    }
 
    @Override
    public ObjectMessage createObjectMessage(final Serializable object) throws JMSException {
       checkClosed();
 
-      ActiveMQObjectMessage msg = new ActiveMQObjectMessage(session);
+      ActiveMQObjectMessage msg = new ActiveMQObjectMessage(session, options);
 
       msg.setObject(object);
 
@@ -308,7 +313,7 @@ public class ActiveMQSession implements QueueSession, TopicSession {
 
          ClientProducer producer = session.createProducer(jbd == null ? null : jbd.getSimpleAddress());
 
-         return new ActiveMQMessageProducer(connection, producer, jbd, session);
+         return new ActiveMQMessageProducer(connection, producer, jbd, session, options);
       }
       catch (ActiveMQException e) {
          throw JMSExceptionHelper.convertFromActiveMQException(e);
@@ -522,6 +527,14 @@ public class ActiveMQSession implements QueueSession, TopicSession {
       return internalCreateSharedConsumer(localTopic, name, messageSelector, ConsumerDurability.DURABLE);
    }
 
+   public String getDeserializationBlackList() {
+      return connection.getDeserializationBlackList();
+   }
+
+   public String getDeserializationWhiteList() {
+      return connection.getDeserializationWhiteList();
+   }
+
    enum ConsumerDurability {
       DURABLE, NON_DURABLE;
    }
@@ -587,7 +600,7 @@ public class ActiveMQSession implements QueueSession, TopicSession {
 
          consumer = session.createConsumer(queueName, null, false);
 
-         ActiveMQMessageConsumer jbc = new ActiveMQMessageConsumer(connection, this, consumer, false, dest, selectorString, autoDeleteQueueName);
+         ActiveMQMessageConsumer jbc = new ActiveMQMessageConsumer(options, connection, this, consumer, false, dest, selectorString, autoDeleteQueueName);
 
          consumers.add(jbc);
 
@@ -739,7 +752,7 @@ public class ActiveMQSession implements QueueSession, TopicSession {
             }
          }
 
-         ActiveMQMessageConsumer jbc = new ActiveMQMessageConsumer(connection, this, consumer, noLocal, dest, selectorString, autoDeleteQueueName);
+         ActiveMQMessageConsumer jbc = new ActiveMQMessageConsumer(options, connection, this, consumer, noLocal, dest, selectorString, autoDeleteQueueName);
 
          consumers.add(jbc);
 
@@ -806,7 +819,7 @@ public class ActiveMQSession implements QueueSession, TopicSession {
          throw JMSExceptionHelper.convertFromActiveMQException(e);
       }
 
-      return new ActiveMQQueueBrowser((ActiveMQQueue) jbq, filterString, session);
+      return new ActiveMQQueueBrowser(options, (ActiveMQQueue) jbq, filterString, session);
 
    }
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/0535218c/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQXAConnection.java
----------------------------------------------------------------------
diff --git a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQXAConnection.java b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQXAConnection.java
index bae4e89..4407fbb 100644
--- a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQXAConnection.java
+++ b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQXAConnection.java
@@ -34,14 +34,15 @@ import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
  */
 public final class ActiveMQXAConnection extends ActiveMQConnection implements XATopicConnection, XAQueueConnection {
 
-   public ActiveMQXAConnection(final String username,
+   public ActiveMQXAConnection(final ConnectionFactoryOptions options,
+                               final String username,
                                final String password,
                                final int connectionType,
                                final String clientID,
                                final int dupsOKBatchSize,
                                final int transactionBatchSize,
                                final ClientSessionFactory sessionFactory) {
-      super(username, password, connectionType, clientID, dupsOKBatchSize, transactionBatchSize, sessionFactory);
+      super(options, username, password, connectionType, clientID, dupsOKBatchSize, transactionBatchSize, sessionFactory);
    }
 
    @Override

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/0535218c/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQXASession.java
----------------------------------------------------------------------
diff --git a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQXASession.java b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQXASession.java
index 815b488..4a7694f 100644
--- a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQXASession.java
+++ b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQXASession.java
@@ -31,12 +31,13 @@ public class ActiveMQXASession extends ActiveMQSession implements XAQueueSession
     * @param session
     * @param sessionType
     */
-   protected ActiveMQXASession(ActiveMQConnection connection,
+   protected ActiveMQXASession(final ConnectionFactoryOptions options,
+                               ActiveMQConnection connection,
                                boolean transacted,
                                boolean xa,
                                int ackMode,
                                ClientSession session,
                                int sessionType) {
-      super(connection, transacted, xa, ackMode, session, sessionType);
+      super(options, connection, transacted, xa, ackMode, session, sessionType);
    }
 }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/0535218c/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ConnectionFactoryOptions.java
----------------------------------------------------------------------
diff --git a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ConnectionFactoryOptions.java b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ConnectionFactoryOptions.java
new file mode 100644
index 0000000..2f27b15
--- /dev/null
+++ b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ConnectionFactoryOptions.java
@@ -0,0 +1,33 @@
+/**
+ * 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.artemis.jms.client;
+
+
+/** Common interface to be used to share common parameters between the RA and client JMS.
+ *  Initially developed to carry on Serialization packages white list but it could eventually be expanded. */
+public interface ConnectionFactoryOptions {
+
+   String getDeserializationBlackList();
+
+   void setDeserializationBlackList(String blackList);
+
+   String getDeserializationWhiteList();
+
+   void setDeserializationWhiteList(String whiteList);
+
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/0535218c/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/JMSMessageListenerWrapper.java
----------------------------------------------------------------------
diff --git a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/JMSMessageListenerWrapper.java b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/JMSMessageListenerWrapper.java
index af5b158..91ea34f 100644
--- a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/JMSMessageListenerWrapper.java
+++ b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/JMSMessageListenerWrapper.java
@@ -28,6 +28,7 @@ import org.apache.activemq.artemis.core.client.impl.ClientSessionInternal;
 
 public class JMSMessageListenerWrapper implements MessageHandler {
 
+   private final ConnectionFactoryOptions options;
    private final ActiveMQConnection connection;
 
    private final ActiveMQSession session;
@@ -40,11 +41,14 @@ public class JMSMessageListenerWrapper implements MessageHandler {
 
    private final boolean individualACK;
 
-   protected JMSMessageListenerWrapper(final ActiveMQConnection connection,
+   protected JMSMessageListenerWrapper(final ConnectionFactoryOptions options,
+                                       final ActiveMQConnection connection,
                                        final ActiveMQSession session,
                                        final ClientConsumer consumer,
                                        final MessageListener listener,
                                        final int ackMode) {
+      this.options = options;
+
       this.connection = connection;
 
       this.session = session;
@@ -64,7 +68,7 @@ public class JMSMessageListenerWrapper implements MessageHandler {
     */
    @Override
    public void onMessage(final ClientMessage message) {
-      ActiveMQMessage msg = ActiveMQMessage.createMessage(message, session.getCoreSession());
+      ActiveMQMessage msg = ActiveMQMessage.createMessage(message, session.getCoreSession(), options);
 
       if (individualACK) {
          msg.setIndividualAcknowledge();

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/0535218c/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/server/config/ConnectionFactoryConfiguration.java
----------------------------------------------------------------------
diff --git a/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/server/config/ConnectionFactoryConfiguration.java b/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/server/config/ConnectionFactoryConfiguration.java
index ab4990c..edba5d1 100644
--- a/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/server/config/ConnectionFactoryConfiguration.java
+++ b/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/server/config/ConnectionFactoryConfiguration.java
@@ -177,4 +177,12 @@ public interface ConnectionFactoryConfiguration extends EncodingSupport {
    String getProtocolManagerFactoryStr();
 
    JMSFactoryType getFactoryType();
+
+   String getDeserializationBlackList();
+
+   void setDeserializationBlackList(String blackList);
+
+   String getDeserializationWhiteList();
+
+   void setDeserializationWhiteList(String whiteList);
 }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/0535218c/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/server/config/impl/ConnectionFactoryConfigurationImpl.java
----------------------------------------------------------------------
diff --git a/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/server/config/impl/ConnectionFactoryConfigurationImpl.java b/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/server/config/impl/ConnectionFactoryConfigurationImpl.java
index 74fcdf4..b72a566 100644
--- a/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/server/config/impl/ConnectionFactoryConfigurationImpl.java
+++ b/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/server/config/impl/ConnectionFactoryConfigurationImpl.java
@@ -118,6 +118,10 @@ public class ConnectionFactoryConfigurationImpl implements ConnectionFactoryConf
 
    private JMSFactoryType factoryType = JMSFactoryType.CF;
 
+   private String deserializationBlackList;
+
+   private String deserializationWhiteList;
+
    // Static --------------------------------------------------------
 
    // Constructors --------------------------------------------------
@@ -614,6 +618,10 @@ public class ConnectionFactoryConfigurationImpl implements ConnectionFactoryConf
       factoryType = JMSFactoryType.valueOf(buffer.readInt());
 
       protocolManagerFactoryStr = BufferHelper.readNullableSimpleStringAsString(buffer);
+
+      deserializationBlackList = BufferHelper.readNullableSimpleStringAsString(buffer);
+
+      deserializationWhiteList = BufferHelper.readNullableSimpleStringAsString(buffer);
    }
 
    @Override
@@ -700,6 +708,10 @@ public class ConnectionFactoryConfigurationImpl implements ConnectionFactoryConf
       buffer.writeInt(factoryType.intValue());
 
       BufferHelper.writeAsNullableSimpleString(buffer, protocolManagerFactoryStr);
+
+      BufferHelper.writeAsNullableSimpleString(buffer, deserializationBlackList);
+
+      BufferHelper.writeAsNullableSimpleString(buffer, deserializationWhiteList);
    }
 
    @Override
@@ -809,7 +821,11 @@ public class ConnectionFactoryConfigurationImpl implements ConnectionFactoryConf
          DataConstants.SIZE_INT +
           // factoryType
 
-         BufferHelper.sizeOfNullableSimpleString(protocolManagerFactoryStr);
+         BufferHelper.sizeOfNullableSimpleString(protocolManagerFactoryStr) +
+
+         BufferHelper.sizeOfNullableSimpleString(deserializationBlackList) +
+
+         BufferHelper.sizeOfNullableSimpleString(deserializationWhiteList);
 
       return size;
    }
@@ -826,6 +842,26 @@ public class ConnectionFactoryConfigurationImpl implements ConnectionFactoryConf
    }
 
    @Override
+   public String getDeserializationBlackList() {
+      return deserializationBlackList;
+   }
+
+   @Override
+   public void setDeserializationBlackList(String blackList) {
+      this.deserializationBlackList = blackList;
+   }
+
+   @Override
+   public String getDeserializationWhiteList() {
+      return this.deserializationWhiteList;
+   }
+
+   @Override
+   public void setDeserializationWhiteList(String whiteList) {
+      this.deserializationWhiteList = whiteList;
+   }
+
+   @Override
    public ConnectionFactoryConfiguration setCompressLargeMessages(boolean compressLargeMessage) {
       this.compressLargeMessage = compressLargeMessage;
       return this;

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/0535218c/artemis-ra/src/main/java/org/apache/activemq/artemis/ra/ActiveMQResourceAdapter.java
----------------------------------------------------------------------
diff --git a/artemis-ra/src/main/java/org/apache/activemq/artemis/ra/ActiveMQResourceAdapter.java b/artemis-ra/src/main/java/org/apache/activemq/artemis/ra/ActiveMQResourceAdapter.java
index 209ae75..2804de2 100644
--- a/artemis-ra/src/main/java/org/apache/activemq/artemis/ra/ActiveMQResourceAdapter.java
+++ b/artemis-ra/src/main/java/org/apache/activemq/artemis/ra/ActiveMQResourceAdapter.java
@@ -901,6 +901,36 @@ public class ActiveMQResourceAdapter implements ResourceAdapter, Serializable {
       raProperties.setProtocolManagerFactoryStr(protocolManagerFactoryStr);
    }
 
+   public String getDeserializationBlackList() {
+      if (ActiveMQResourceAdapter.trace) {
+         ActiveMQRALogger.LOGGER.trace("getDeserializationBlackList()");
+      }
+      return raProperties.getDeserializationBlackList();
+   }
+
+   public void setDeserializationBlackList(String deserializationBlackList) {
+      if (ActiveMQResourceAdapter.trace) {
+         ActiveMQRALogger.LOGGER.trace("setDeserializationBlackList(" + deserializationBlackList + ")");
+      }
+
+      raProperties.setDeserializationBlackList(deserializationBlackList);
+   }
+
+   public String getDeserializationWhiteList() {
+      if (ActiveMQResourceAdapter.trace) {
+         ActiveMQRALogger.LOGGER.trace("getDeserializationWhiteList()");
+      }
+      return raProperties.getDeserializationWhiteList();
+   }
+
+   public void setDeserializationWhiteList(String deserializationWhiteList) {
+      if (ActiveMQResourceAdapter.trace) {
+         ActiveMQRALogger.LOGGER.trace("setDeserializationWhiteList(" + deserializationWhiteList + ")");
+      }
+
+      raProperties.setDeserializationWhiteList(deserializationWhiteList);
+   }
+
    /**
     * Get min large message size
     *
@@ -2004,6 +2034,14 @@ public class ActiveMQResourceAdapter implements ResourceAdapter, Serializable {
       if (val5 != null) {
          cf.setProtocolManagerFactoryStr(val5);
       }
+      val5 = overrideProperties.getDeserializationBlackList() != null ? overrideProperties.getDeserializationBlackList() : raProperties.getDeserializationBlackList();
+      if (val5 != null) {
+         cf.setDeserializationBlackList(val5);
+      }
+      val5 = overrideProperties.getDeserializationWhiteList() != null ? overrideProperties.getDeserializationWhiteList() : raProperties.getDeserializationWhiteList();
+      if (val5 != null) {
+         cf.setDeserializationWhiteList(val5);
+      }
    }
 
    public void setManagedConnectionFactory(ActiveMQRAManagedConnectionFactory activeMQRAManagedConnectionFactory) {

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/0535218c/artemis-ra/src/main/java/org/apache/activemq/artemis/ra/ConnectionFactoryProperties.java
----------------------------------------------------------------------
diff --git a/artemis-ra/src/main/java/org/apache/activemq/artemis/ra/ConnectionFactoryProperties.java b/artemis-ra/src/main/java/org/apache/activemq/artemis/ra/ConnectionFactoryProperties.java
index 2137186..ff7817e 100644
--- a/artemis-ra/src/main/java/org/apache/activemq/artemis/ra/ConnectionFactoryProperties.java
+++ b/artemis-ra/src/main/java/org/apache/activemq/artemis/ra/ConnectionFactoryProperties.java
@@ -19,7 +19,9 @@ package org.apache.activemq.artemis.ra;
 import java.util.List;
 import java.util.Map;
 
-public class ConnectionFactoryProperties {
+import org.apache.activemq.artemis.jms.client.ConnectionFactoryOptions;
+
+public class ConnectionFactoryProperties implements ConnectionFactoryOptions {
 
    /**
     * Trace enabled
@@ -120,6 +122,10 @@ public class ConnectionFactoryProperties {
 
    private String protocolManagerFactoryStr;
 
+   private String deserializationBlackList;
+
+   private String deserializationWhiteList;
+
    /**
     * @return the transportType
     */
@@ -689,6 +695,28 @@ public class ConnectionFactoryProperties {
       this.protocolManagerFactoryStr = protocolManagerFactoryStr;
    }
 
+   @Override
+   public String getDeserializationBlackList() {
+      return deserializationBlackList;
+   }
+
+   @Override
+   public void setDeserializationBlackList(String deserializationBlackList) {
+      this.deserializationBlackList = deserializationBlackList;
+      hasBeenUpdated = true;
+   }
+
+   @Override
+   public String getDeserializationWhiteList() {
+      return this.deserializationWhiteList;
+   }
+
+   @Override
+   public void setDeserializationWhiteList(String deserializationWhiteList) {
+      this.deserializationWhiteList = deserializationWhiteList;
+      hasBeenUpdated = true;
+   }
+
    public boolean isHasBeenUpdated() {
       return hasBeenUpdated;
    }
@@ -960,6 +988,20 @@ public class ConnectionFactoryProperties {
       }
       else if (!connectionParameters.equals(other.connectionParameters))
          return false;
+
+      if (deserializationBlackList == null) {
+         if (other.deserializationBlackList != null)
+            return false;
+      }
+      else if (!deserializationBlackList.equals(other.deserializationBlackList))
+         return false;
+
+      if (deserializationWhiteList == null) {
+         if (other.deserializationWhiteList != null)
+            return false;
+      }
+      else if (!deserializationWhiteList.equals(other.deserializationWhiteList))
+         return false;
       return true;
    }
 
@@ -1010,6 +1052,8 @@ public class ConnectionFactoryProperties {
       result = prime * result + ((groupID == null) ? 0 : groupID.hashCode());
       result = prime * result + ((connectorClassName == null) ? 0 : connectorClassName.hashCode());
       result = prime * result + ((connectionParameters == null) ? 0 : connectionParameters.hashCode());
+      result = prime * result + ((deserializationBlackList == null) ? 0 : deserializationBlackList.hashCode());
+      result = prime * result + ((deserializationWhiteList == null) ? 0 : deserializationWhiteList.hashCode());
       return result;
    }
 }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/0535218c/artemis-ra/src/main/java/org/apache/activemq/artemis/ra/inflow/ActiveMQActivation.java
----------------------------------------------------------------------
diff --git a/artemis-ra/src/main/java/org/apache/activemq/artemis/ra/inflow/ActiveMQActivation.java b/artemis-ra/src/main/java/org/apache/activemq/artemis/ra/inflow/ActiveMQActivation.java
index 510e680..a9057d0 100644
--- a/artemis-ra/src/main/java/org/apache/activemq/artemis/ra/inflow/ActiveMQActivation.java
+++ b/artemis-ra/src/main/java/org/apache/activemq/artemis/ra/inflow/ActiveMQActivation.java
@@ -315,7 +315,7 @@ public class ActiveMQActivation {
          try {
             cf = factory.getServerLocator().createSessionFactory();
             session = setupSession(cf);
-            ActiveMQMessageHandler handler = new ActiveMQMessageHandler(this, ra.getTM(), (ClientSessionInternal) session, cf, i);
+            ActiveMQMessageHandler handler = new ActiveMQMessageHandler(factory, this, ra.getTM(), (ClientSessionInternal) session, cf, i);
             handler.setup();
             handlers.add(handler);
          }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/0535218c/artemis-ra/src/main/java/org/apache/activemq/artemis/ra/inflow/ActiveMQMessageHandler.java
----------------------------------------------------------------------
diff --git a/artemis-ra/src/main/java/org/apache/activemq/artemis/ra/inflow/ActiveMQMessageHandler.java b/artemis-ra/src/main/java/org/apache/activemq/artemis/ra/inflow/ActiveMQMessageHandler.java
index b0d64cc..353bc73 100644
--- a/artemis-ra/src/main/java/org/apache/activemq/artemis/ra/inflow/ActiveMQMessageHandler.java
+++ b/artemis-ra/src/main/java/org/apache/activemq/artemis/ra/inflow/ActiveMQMessageHandler.java
@@ -40,6 +40,7 @@ import org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryInternal
 import org.apache.activemq.artemis.core.client.impl.ClientSessionInternal;
 import org.apache.activemq.artemis.jms.client.ActiveMQDestination;
 import org.apache.activemq.artemis.jms.client.ActiveMQMessage;
+import org.apache.activemq.artemis.jms.client.ConnectionFactoryOptions;
 import org.apache.activemq.artemis.ra.ActiveMQRALogger;
 import org.apache.activemq.artemis.ra.ActiveMQResourceAdapter;
 import org.apache.activemq.artemis.service.extensions.ServiceUtils;
@@ -68,6 +69,8 @@ public class ActiveMQMessageHandler implements MessageHandler, FailoverEventList
     */
    private MessageEndpoint endpoint;
 
+   private final ConnectionFactoryOptions options;
+
    private final ActiveMQActivation activation;
 
    private boolean useLocalTx;
@@ -84,11 +87,13 @@ public class ActiveMQMessageHandler implements MessageHandler, FailoverEventList
 
    private volatile boolean connected;
 
-   public ActiveMQMessageHandler(final ActiveMQActivation activation,
+   public ActiveMQMessageHandler(final ConnectionFactoryOptions options,
+                                 final ActiveMQActivation activation,
                                  final TransactionManager tm,
                                  final ClientSessionInternal session,
                                  final ClientSessionFactory cf,
                                  final int sessionNr) {
+      this.options = options;
       this.activation = activation;
       this.session = session;
       this.cf = cf;
@@ -286,7 +291,7 @@ public class ActiveMQMessageHandler implements MessageHandler, FailoverEventList
          ActiveMQRALogger.LOGGER.trace("onMessage(" + message + ")");
       }
 
-      ActiveMQMessage msg = ActiveMQMessage.createMessage(message, session);
+      ActiveMQMessage msg = ActiveMQMessage.createMessage(message, session, options);
       boolean beforeDelivery = false;
 
       try {

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/0535218c/docs/user-manual/en/security.md
----------------------------------------------------------------------
diff --git a/docs/user-manual/en/security.md b/docs/user-manual/en/security.md
index 0f6517a..4b06f25 100644
--- a/docs/user-manual/en/security.md
+++ b/docs/user-manual/en/security.md
@@ -690,3 +690,77 @@ You will have to configure a few extra properties desribed as below.
 -   `trustStorePath` - The path of the trust store file. This is needed only if `clientAuth` is `true`.
 
 -   `trustStorePassword` - The trust store's password.
+
+## Controlling JMS ObjectMessage deserialization
+
+Artemis provides a simple class filtering mechanism with which a user can specify which
+packages are to be trusted and which are not. Objects whose classes are from trusted packages
+can be deserialized without problem, whereas those from 'not trusted' packages will be denied
+deserialization.
+
+Artemis keeps a `black list` to keep track of packages that are not trusted and a `white list`
+for trusted packages. By default both lists are empty, meaning any serializable object is 
+allowed to be deserialized. If an object whose class matches one of the packages in black list,
+it is not allowed to be deserialized. If it matches one in the white list
+the object can be deserialized. If a package appears in both black list and white list, 
+the one in black list takes precedence. If a class neither matches with `black list` 
+nor with the `white list`, the class deserialization will be denied 
+unless the white list is empty (meaning the user doesn't specify the white list at all).
+
+A class is considered as a 'match' if
+
+-   its full name exactly matches one of the entries in the list.
+-   its package matches one of the entries in the list or is a sub-package of one of the entries.
+
+For example, if a class full name is "org.apache.pkg1.Class1", some matching entries could be:
+
+-   `org.apache.pkg1.Class1` - exact match.
+-   `org.apache.pkg1` - exact package match.
+-   `org.apache` -- sub package match.
+
+A `*` means 'match-all' in a black or white list.
+
+### Specifying black list and white list via Connection Factories
+
+To specify the white and black lists one can append properties `deserializationBlackList` and `deserializationWhiteList` respectively
+to a Connection Factory's url string. For example:
+
+     ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("vm://0?deserializationBlackList=org.apache.pkg1,org.some.pkg2");
+
+The above statement creates a factory that has a black list contains two forbidden packages, "org.apache.pkg1" and "org.some.pkg2",
+separated by a comma.
+
+You can also set the values via ActiveMQConnectionFactory's API:
+
+    public void setDeserializationBlackList(String blackList);
+    public void setDeserializationWhiteList(String whiteList);
+   
+Again the parameters are comma separated list of package/class names.
+
+### Specifying black list and white list via system properties
+
+There are two system properties available for specifying black list and white list:
+
+-   `org.apache.activemq.artemis.jms.deserialization.whitelist` - comma separated list of entries for the white list.
+-   `org.apache.activemq.artemis.jms.deserialization.blacklist` - comma separated list of entries for the black list.
+
+Once defined, all JMS object message deserialization in the VM is subject to checks against the two lists. However if you create a ConnectionFactory
+and set a new set of black/white lists on it, the new values will override the system properties.
+
+### Specifying black list and white list for resource adapters
+
+Message beans using a JMS resource adapter to receive messages can also control their object deserialization via properly configuring relevant
+properties for their resource adapters. There are two properties that you can configure with connection factories in a resource adapter:
+
+-   `deserializationBlackList` - comma separated values for black list
+-   `deserializationWhiteList` - comma separated values for white list
+
+These properties, once specified, are eventually set on the corresponding internal factories.
+
+
+
+
+
+
+
+

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/0535218c/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/ActiveMQConnectionFactoryTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/ActiveMQConnectionFactoryTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/ActiveMQConnectionFactoryTest.java
index 9e8bc8f..a40cb07 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/ActiveMQConnectionFactoryTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/ActiveMQConnectionFactoryTest.java
@@ -16,22 +16,34 @@
  */
 package org.apache.activemq.artemis.tests.integration.jms;
 
+import org.apache.activemq.artemis.api.core.SimpleString;
 import org.apache.activemq.artemis.tests.integration.IntegrationTestLogger;
+import org.apache.activemq.artemis.tests.integration.jms.serializables.TestClass1;
 import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
+import org.apache.activemq.artemis.utils.ObjectInputStreamWithClassLoader;
 import org.apache.activemq.artemis.utils.RandomUtil;
 import org.apache.activemq.artemis.core.config.ha.SharedStoreMasterPolicyConfiguration;
 import org.junit.Before;
 
 import org.junit.Test;
 
+import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.Hashtable;
 import java.util.List;
 import java.util.Map;
 
 import javax.jms.Connection;
 import javax.jms.JMSException;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+import javax.jms.ObjectMessage;
+import javax.jms.Queue;
+import javax.jms.QueueBrowser;
 import javax.jms.Session;
+import javax.naming.Context;
+import javax.naming.InitialContext;
 
 import org.junit.Assert;
 
@@ -213,6 +225,217 @@ public class ActiveMQConnectionFactoryTest extends ActiveMQTestBase {
       cf.close();
    }
 
+   @Test
+   public void testDeserializationOptions() throws Exception {
+      testDeserializationOptions(false, false);
+   }
+
+   @Test
+   public void testDeserializationOptionsJndi() throws Exception {
+      testDeserializationOptions(true, false);
+   }
+
+   @Test
+   public void testDeserializationOptionsBrowser() throws Exception {
+      testDeserializationOptions(false, true);
+   }
+
+   @Test
+   public void testDeserializationOptionsJndiBrowser() throws Exception {
+      testDeserializationOptions(true, true);
+   }
+
+   private void testDeserializationOptions(boolean useJndi, boolean useBrowser) throws Exception {
+      String qname = "SerialTestQueue";
+      SimpleString qaddr = new SimpleString("jms.queue." + qname);
+      liveService.createQueue(qaddr, qaddr, null, true, false);
+
+      //default ok
+      String blackList = null;
+      String whiteList = null;
+      Object obj = receiveObjectMessage(blackList, whiteList, qname, new TestClass1(), useJndi, useBrowser);
+      assertTrue("Object is " + obj, obj instanceof TestClass1);
+
+      //not in the white list
+      blackList = "java.lang";
+      whiteList = "some.other.package1";
+      obj = receiveObjectMessage(blackList, whiteList, qname, new TestClass1(), useJndi, useBrowser);
+      assertTrue("Object is " + obj, obj instanceof JMSException);
+      //but String always trusted
+      obj = receiveObjectMessage(blackList, whiteList, qname, new String("hello"), useJndi, useBrowser);
+      assertTrue("java.lang.String always trusted ", "hello".equals(obj));
+
+      //in the blacklist
+      blackList = "org.apache.activemq.artemis.tests.integration.jms.serializables";
+      whiteList = "org.apache.activemq.artemis.tests.integration.jms.serializables";
+      obj = receiveObjectMessage(blackList, whiteList, qname, new TestClass1(), useJndi, useBrowser);
+      assertTrue("Object is " + obj, obj instanceof JMSException);
+
+      //black list parent package
+      blackList = "org.apache.activemq.artemis";
+      whiteList = "org.apache.activemq.artemis.tests.integration.jms.serializables";
+      obj = receiveObjectMessage(blackList, whiteList, qname, new TestClass1(), useJndi, useBrowser);
+      assertTrue("Object is " + obj, obj instanceof JMSException);
+
+      //in white list
+      blackList = "some.other.package";
+      whiteList = "org.apache.activemq.artemis.tests.integration.jms.serializables";
+      obj = receiveObjectMessage(blackList, whiteList, qname, new TestClass1(), useJndi, useBrowser);
+      assertTrue("Object is " + obj, obj instanceof TestClass1);
+
+      //parent in white list
+      blackList = "some.other.package";
+      whiteList = "org.apache.activemq.artemis.tests.integration.jms";
+      obj = receiveObjectMessage(blackList, whiteList, qname, new TestClass1(), useJndi, useBrowser);
+      assertTrue("Object is " + obj, obj instanceof TestClass1);
+
+      //sub package in white list
+      blackList = "some.other.package";
+      whiteList = "org.apache.activemq.artemis.tests.integration.jms.serializables.pkg1";
+      obj = receiveObjectMessage(blackList, whiteList, qname, new TestClass1(), useJndi, useBrowser);
+      assertTrue("Object is " + obj, obj instanceof JMSException);
+
+      //wild card white list but black listed
+      blackList = "org.apache.activemq.artemis.tests.integration.jms.serializables";
+      whiteList = "*";
+      obj = receiveObjectMessage(blackList, whiteList, qname, new TestClass1(), useJndi, useBrowser);
+      assertTrue("Object is " + obj, obj instanceof JMSException);
+
+      //wild card white list and not black listed
+      blackList = "some.other.package";
+      whiteList = "*";
+      obj = receiveObjectMessage(blackList, whiteList, qname, new TestClass1(), useJndi, useBrowser);
+      assertTrue("Object is " + obj, obj instanceof TestClass1);
+
+      //wild card black list
+      blackList = "*";
+      whiteList = "*";
+      obj = receiveObjectMessage(blackList, whiteList, qname, new TestClass1(), useJndi, useBrowser);
+      assertTrue("Object is " + obj, obj instanceof JMSException);
+   }
+
+   @Test
+   public void testSystemPropertyBlackWhiteListDefault() throws Exception {
+      System.setProperty(ObjectInputStreamWithClassLoader.BLACKLIST_PROPERTY, "*");
+      System.setProperty(ObjectInputStreamWithClassLoader.WHITELIST_PROPERTY, "some.other.package");
+
+      String qname = "SerialTestQueue";
+      SimpleString qaddr = new SimpleString("jms.queue." + qname);
+      liveService.createQueue(qaddr, qaddr, null, true, false);
+
+      try {
+         String blackList = null;
+         String whiteList = null;
+         Object obj = receiveObjectMessage(blackList, whiteList, qname, new TestClass1(), false, false);
+         assertTrue("Object is " + obj, obj instanceof JMSException);
+         //but String always trusted
+         obj = receiveObjectMessage(blackList, whiteList, qname, new String("hello"), false, false);
+         assertTrue("java.lang.String always trusted " + obj, "hello".equals(obj));
+
+         //override
+         blackList = "some.other.package";
+         whiteList = "org.apache.activemq.artemis.tests.integration";
+         obj = receiveObjectMessage(blackList, whiteList, qname, new TestClass1(), false, false);
+         assertTrue("Object is " + obj, obj instanceof TestClass1);
+         //but String always trusted
+         obj = receiveObjectMessage(blackList, whiteList, qname, new String("hello"), false, false);
+         assertTrue("java.lang.String always trusted " + obj, "hello".equals(obj));
+      }
+      finally {
+         System.clearProperty(ObjectInputStreamWithClassLoader.BLACKLIST_PROPERTY);
+         System.clearProperty(ObjectInputStreamWithClassLoader.WHITELIST_PROPERTY);
+      }
+   }
+
+   private Object receiveObjectMessage(String blackList, String whiteList, String qname,
+                                       Serializable obj, boolean useJndi, boolean useBrowser) throws Exception {
+      sendObjectMessage(qname, obj);
+
+      StringBuilder query = new StringBuilder("");
+      if (blackList != null) {
+         query.append("?");
+         query.append("deserializationBlackList=");
+         query.append(blackList);
+
+         if (whiteList != null) {
+            query.append("&");
+            query.append("deserializationWhiteList=");
+            query.append(whiteList);
+         }
+      }
+      else {
+         if (whiteList != null) {
+            query.append("?deserializationWhiteList=");
+            query.append(whiteList);
+         }
+      }
+
+      System.out.println("query string: " + query);
+      ActiveMQConnectionFactory factory = null;
+      if (useJndi) {
+         Hashtable<String, Object> props = new Hashtable<>();
+         props.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory");
+         props.put("connectionFactory.VmConnectionFactory", "vm://0" + query);
+         Context ctx = new InitialContext(props);
+         factory = (ActiveMQConnectionFactory) ctx.lookup("VmConnectionFactory");
+      }
+      else {
+         factory = new ActiveMQConnectionFactory("vm://0" + query);
+      }
+      Connection connection = null;
+      try {
+         connection = factory.createConnection();
+         connection.start();
+         Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+         Queue queue = session.createQueue(qname);
+         Object result = null;
+         if (useBrowser) {
+            QueueBrowser browser = session.createBrowser(queue);
+            ObjectMessage objMessage = (ObjectMessage) browser.getEnumeration().nextElement();
+            //drain message before triggering deserialization
+            MessageConsumer consumer = session.createConsumer(queue);
+            consumer.receive(5000);
+            result = objMessage.getObject();
+         }
+         else {
+            MessageConsumer consumer = session.createConsumer(queue);
+            ObjectMessage objMessage = (ObjectMessage) consumer.receive(5000);
+            assertNotNull(objMessage);
+            result = objMessage.getObject();
+         }
+         return result;
+      }
+      catch (Exception e) {
+         return e;
+      }
+      finally {
+         if (connection != null) {
+            try {
+               connection.close();
+            }
+            catch (JMSException e) {
+               return e;
+            }
+         }
+      }
+   }
+
+   private void sendObjectMessage(String qname, Serializable obj) throws Exception {
+      ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("vm://0");
+      Connection connection = factory.createConnection();
+      try {
+         Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+         Queue q = session.createQueue(qname);
+         MessageProducer producer = session.createProducer(q);
+         ObjectMessage objMessage = session.createObjectMessage();
+         objMessage.setObject(obj);
+         producer.send(objMessage);
+      }
+      finally {
+         connection.close();
+      }
+   }
+
    private void testSettersThrowException(final ActiveMQConnectionFactory cf) {
 
       String clientID = RandomUtil.randomString();

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/0535218c/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/serializables/TestClass1.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/serializables/TestClass1.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/serializables/TestClass1.java
new file mode 100644
index 0000000..ec73aa5
--- /dev/null
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/serializables/TestClass1.java
@@ -0,0 +1,22 @@
+/*
+ * 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.artemis.tests.integration.jms.serializables;
+
+import java.io.Serializable;
+
+public class TestClass1 implements Serializable {
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/0535218c/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/ra/ActiveMQMessageHandlerTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/ra/ActiveMQMessageHandlerTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/ra/ActiveMQMessageHandlerTest.java
index 0aab4c5..5101cd8 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/ra/ActiveMQMessageHandlerTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/ra/ActiveMQMessageHandlerTest.java
@@ -26,15 +26,23 @@ import org.apache.activemq.artemis.api.core.client.SessionFailureListener;
 import org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryInternal;
 import org.apache.activemq.artemis.core.postoffice.Binding;
 import org.apache.activemq.artemis.core.postoffice.impl.LocalQueueBinding;
+import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory;
 import org.apache.activemq.artemis.ra.ActiveMQResourceAdapter;
 import org.apache.activemq.artemis.ra.inflow.ActiveMQActivation;
 import org.apache.activemq.artemis.ra.inflow.ActiveMQActivationSpec;
 import org.apache.activemq.artemis.tests.integration.IntegrationTestLogger;
 import org.junit.Test;
 
+import javax.jms.Connection;
+import javax.jms.JMSException;
 import javax.jms.Message;
+import javax.jms.MessageProducer;
+import javax.jms.ObjectMessage;
+import javax.jms.Queue;
+import javax.jms.Session;
 import javax.resource.ResourceException;
 import javax.resource.spi.InvalidPropertyException;
+import java.io.Serializable;
 import java.lang.reflect.Method;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
@@ -79,6 +87,103 @@ public class ActiveMQMessageHandlerTest extends ActiveMQRATestBase {
    }
 
    @Test
+   public void testObjectMessageReceiveSerializationControl() throws Exception {
+      String blackList = "org.apache.activemq.artemis.tests.integration.ra";
+      String whiteList = "*";
+      testDeserialization(blackList, whiteList, false);
+   }
+
+   @Test
+   public void testObjectMessageReceiveSerializationControl1() throws Exception {
+      String blackList = "some.other.pkg";
+      String whiteList = "org.apache.activemq.artemis.tests.integration.ra";
+      testDeserialization(blackList, whiteList, true);
+   }
+
+   @Test
+   public void testObjectMessageReceiveSerializationControl2() throws Exception {
+      String blackList = "*";
+      String whiteList = "org.apache.activemq.artemis.tests.integration.ra";
+      testDeserialization(blackList, whiteList, false);
+   }
+
+   @Test
+   public void testObjectMessageReceiveSerializationControl3() throws Exception {
+      String blackList = "org.apache.activemq.artemis.tests";
+      String whiteList = "org.apache.activemq.artemis.tests.integration.ra";
+      testDeserialization(blackList, whiteList, false);
+   }
+
+   @Test
+   public void testObjectMessageReceiveSerializationControl4() throws Exception {
+      String blackList = null;
+      String whiteList = "some.other.pkg";
+      testDeserialization(blackList, whiteList, false);
+   }
+
+   @Test
+   public void testObjectMessageReceiveSerializationControl5() throws Exception {
+      String blackList = null;
+      String whiteList = null;
+      testDeserialization(blackList, whiteList, true);
+   }
+
+   private void testDeserialization(String blackList, String whiteList, boolean shouldSucceed) throws Exception {
+      ActiveMQResourceAdapter qResourceAdapter = newResourceAdapter();
+      qResourceAdapter.setDeserializationBlackList(blackList);
+      qResourceAdapter.setDeserializationWhiteList(whiteList);
+
+      MyBootstrapContext ctx = new MyBootstrapContext();
+      qResourceAdapter.start(ctx);
+
+      ActiveMQActivationSpec spec = new ActiveMQActivationSpec();
+      spec.setResourceAdapter(qResourceAdapter);
+      spec.setUseJNDI(false);
+      spec.setDestinationType("javax.jms.Queue");
+      spec.setDestination(MDBQUEUE);
+      qResourceAdapter.setConnectorClassName(INVM_CONNECTOR_FACTORY);
+      CountDownLatch latch = new CountDownLatch(1);
+      DummyMessageEndpoint endpoint = new DummyMessageEndpoint(latch);
+      DummyMessageEndpointFactory endpointFactory = new DummyMessageEndpointFactory(endpoint, false);
+      qResourceAdapter.endpointActivation(endpointFactory, spec);
+
+      //send using jms
+      ActiveMQConnectionFactory jmsFactory = new ActiveMQConnectionFactory("vm://0");
+      Connection connection = jmsFactory.createConnection();
+
+      try {
+         Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+         Queue jmsQueue = session.createQueue(MDBQUEUE);
+         ObjectMessage objMsg = session.createObjectMessage();
+         objMsg.setObject(new DummySerializable());
+         MessageProducer producer = session.createProducer(jmsQueue);
+         producer.send(objMsg);
+      }
+      finally {
+         connection.close();
+      }
+
+      latch.await(5, TimeUnit.SECONDS);
+
+      assertNotNull(endpoint.lastMessage);
+
+      ObjectMessage objMsg = (ObjectMessage) endpoint.lastMessage;
+
+      try {
+         Object obj = objMsg.getObject();
+         assertTrue("deserialization should fail but got: " + obj, shouldSucceed);
+         assertTrue(obj instanceof DummySerializable);
+      }
+      catch (JMSException e) {
+         assertFalse("got unexpected exception: " + e, shouldSucceed);
+      }
+
+      qResourceAdapter.endpointDeactivation(endpointFactory, spec);
+
+      qResourceAdapter.stop();
+   }
+
+   @Test
    public void testSimpleMessageReceivedOnQueueManyMessages() throws Exception {
       ActiveMQResourceAdapter qResourceAdapter = newResourceAdapter();
       MyBootstrapContext ctx = new MyBootstrapContext();
@@ -863,4 +968,7 @@ public class ActiveMQMessageHandlerTest extends ActiveMQRATestBase {
          }
       }
    }
+
+   static class DummySerializable implements Serializable {
+   }
 }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/0535218c/tests/jms-tests/src/test/java/org/apache/activemq/artemis/jms/tests/message/MessageHeaderTest.java
----------------------------------------------------------------------
diff --git a/tests/jms-tests/src/test/java/org/apache/activemq/artemis/jms/tests/message/MessageHeaderTest.java b/tests/jms-tests/src/test/java/org/apache/activemq/artemis/jms/tests/message/MessageHeaderTest.java
index ad2e8d2..dcb5d2f 100644
--- a/tests/jms-tests/src/test/java/org/apache/activemq/artemis/jms/tests/message/MessageHeaderTest.java
+++ b/tests/jms-tests/src/test/java/org/apache/activemq/artemis/jms/tests/message/MessageHeaderTest.java
@@ -739,7 +739,7 @@ public class MessageHeaderTest extends MessageHeaderTestBase {
 
       ObjectMessage foreignObjectMessage = new SimpleJMSObjectMessage();
 
-      ActiveMQObjectMessage copy = new ActiveMQObjectMessage(foreignObjectMessage, session);
+      ActiveMQObjectMessage copy = new ActiveMQObjectMessage(foreignObjectMessage, session, null);
 
       MessageHeaderTestBase.ensureEquivalent(foreignObjectMessage, copy);
    }


Mime
View raw message