PROTON-2188: throw IAE for map entries with unknown key/value type rather than just NPE
diff --git a/proton-j/src/main/java/org/apache/qpid/proton/codec/MapType.java b/proton-j/src/main/java/org/apache/qpid/proton/codec/MapType.java
index 78106ce..d73351e 100644
--- a/proton-j/src/main/java/org/apache/qpid/proton/codec/MapType.java
+++ b/proton-j/src/main/java/org/apache/qpid/proton/codec/MapType.java
@@ -90,7 +90,12 @@
if (fixedKeyType == null)
{
- elementEncoding = _encoder.getType(element.getKey()).getEncoding(element.getKey());
+ AMQPType keyType = _encoder.getType(element.getKey());
+ if(keyType == null) {
+ throw new IllegalArgumentException(
+ "No encoding is known for map entry key of type: " + element.getKey().getClass().getName());
+ }
+ elementEncoding = keyType.getEncoding(element.getKey());
}
else
{
@@ -98,7 +103,14 @@
}
len += elementEncoding.getConstructorSize() + elementEncoding.getValueSize(element.getKey());
- elementEncoding = _encoder.getType(element.getValue()).getEncoding(element.getValue());
+
+ AMQPType valueType = _encoder.getType(element.getValue());
+ if(valueType == null) {
+ throw new IllegalArgumentException(
+ "No encoding is known for map entry value of type: " + element.getValue().getClass().getName());
+ }
+
+ elementEncoding = valueType.getEncoding(element.getValue());
len += elementEncoding.getConstructorSize() + elementEncoding.getValueSize(element.getValue());
}
} finally {
diff --git a/proton-j/src/test/java/org/apache/qpid/proton/codec/ListTypeCodecTest.java b/proton-j/src/test/java/org/apache/qpid/proton/codec/ListTypeCodecTest.java
index 3e964c8..b486fd1 100644
--- a/proton-j/src/test/java/org/apache/qpid/proton/codec/ListTypeCodecTest.java
+++ b/proton-j/src/test/java/org/apache/qpid/proton/codec/ListTypeCodecTest.java
@@ -16,9 +16,12 @@
*/
package org.apache.qpid.proton.codec;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.StringContains.containsString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import java.io.IOException;
import java.util.ArrayList;
@@ -144,4 +147,32 @@
// Check that the ListType tries to reserve space, actual encoding size not computed here.
Mockito.verify(spy).ensureRemaining(Mockito.anyInt());
}
+
+ @Test
+ public void testEncodeListWithUnknownEntryType() throws Exception {
+ List<Object> list = new ArrayList<>();
+ list.add(new MyUnknownTestType());
+
+ doTestEncodeListWithUnknownEntryTypeTestImpl(list);
+ }
+
+ @Test
+ public void testEncodeSubListWithUnknownEntryType() throws Exception {
+ List<Object> subList = new ArrayList<>();
+ subList.add(new MyUnknownTestType());
+
+ List<Object> list = new ArrayList<>();
+ list.add(subList);
+
+ doTestEncodeListWithUnknownEntryTypeTestImpl(list);
+ }
+
+ private void doTestEncodeListWithUnknownEntryTypeTestImpl(List<Object> list) {
+ try {
+ encoder.writeList(list);
+ fail("Expected exception to be thrown");
+ } catch (IllegalArgumentException iae) {
+ assertThat(iae.getMessage(), containsString("No encoding defined for type: class org.apache.qpid.proton.codec.MyUnknownTestType"));
+ }
+ }
}
diff --git a/proton-j/src/test/java/org/apache/qpid/proton/codec/MapTypeCodecTest.java b/proton-j/src/test/java/org/apache/qpid/proton/codec/MapTypeCodecTest.java
index 73b4a70..b0762fb 100644
--- a/proton-j/src/test/java/org/apache/qpid/proton/codec/MapTypeCodecTest.java
+++ b/proton-j/src/test/java/org/apache/qpid/proton/codec/MapTypeCodecTest.java
@@ -16,9 +16,12 @@
*/
package org.apache.qpid.proton.codec;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.StringContains.containsString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import java.io.IOException;
import java.util.HashMap;
@@ -123,4 +126,60 @@
// Check that the MapType tries to reserve space, actual encoding size not computed here.
Mockito.verify(spy).ensureRemaining(Mockito.anyInt());
}
+
+ @Test
+ public void testEncodeMapWithUnknownEntryValueType() throws Exception {
+ Map<String, Object> map = new HashMap<>();
+ map.put("unknown", new MyUnknownTestType());
+
+ doTestEncodeMapWithUnknownEntryValueTypeTestImpl(map);
+ }
+
+ @Test
+ public void testEncodeSubMapWithUnknownEntryValueType() throws Exception {
+ Map<String, Object> subMap = new HashMap<>();
+ subMap.put("unknown", new MyUnknownTestType());
+
+ Map<String, Object> map = new HashMap<>();
+ map.put("submap", subMap);
+
+ doTestEncodeMapWithUnknownEntryValueTypeTestImpl(map);
+ }
+
+ private void doTestEncodeMapWithUnknownEntryValueTypeTestImpl(Map<String, Object> map) {
+ try {
+ encoder.writeMap(map);
+ fail("Expected exception to be thrown");
+ } catch (IllegalArgumentException iae) {
+ assertThat(iae.getMessage(), containsString("No encoding is known for map entry value of type: org.apache.qpid.proton.codec.MyUnknownTestType"));
+ }
+ }
+
+ @Test
+ public void testEncodeMapWithUnknownEntryKeyType() throws Exception {
+ Map<Object, String> map = new HashMap<>();
+ map.put(new MyUnknownTestType(), "unknown");
+
+ doTestEncodeMapWithUnknownEntryKeyTypeTestImpl(map);
+ }
+
+ @Test
+ public void testEncodeSubMapWithUnknownEntryKeyType() throws Exception {
+ Map<Object, String> subMap = new HashMap<>();
+ subMap.put(new MyUnknownTestType(), "unknown");
+
+ Map<String, Object> map = new HashMap<>();
+ map.put("submap", subMap);
+
+ doTestEncodeMapWithUnknownEntryKeyTypeTestImpl(map);
+ }
+
+ private void doTestEncodeMapWithUnknownEntryKeyTypeTestImpl(Map<?, ?> map) {
+ try {
+ encoder.writeMap(map);
+ fail("Expected exception to be thrown");
+ } catch (IllegalArgumentException iae) {
+ assertThat(iae.getMessage(), containsString("No encoding is known for map entry key of type: org.apache.qpid.proton.codec.MyUnknownTestType"));
+ }
+ }
}
diff --git a/proton-j/src/test/java/org/apache/qpid/proton/codec/MyUnknownTestType.java b/proton-j/src/test/java/org/apache/qpid/proton/codec/MyUnknownTestType.java
new file mode 100644
index 0000000..a8e0b05
--- /dev/null
+++ b/proton-j/src/test/java/org/apache/qpid/proton/codec/MyUnknownTestType.java
@@ -0,0 +1,21 @@
+/*
+ * 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.qpid.proton.codec;
+
+class MyUnknownTestType {
+
+}
\ No newline at end of file