Merge branch '2.8' into 2.9
diff --git a/release-notes/CREDITS-2.x b/release-notes/CREDITS-2.x
index 3d50e73..eea9aa5 100644
--- a/release-notes/CREDITS-2.x
+++ b/release-notes/CREDITS-2.x
@@ -653,6 +653,10 @@
   * Reported #2032: Blacklist another serialization gadget (ibatis)
    (2.8.11.2)
 
+svarzee@github
+  * Reported #2109, suggested fix: Canonical string for reference type is built incorrectly
+   (2.8.11.3 / 2.9.7)
+
 Connor Kuhn (ckuhn@github)
   * Contributed #1341: FAIL_ON_MISSING_EXTERNAL_TYPE_ID_PROPERTY
    (2.9.0)
diff --git a/release-notes/VERSION-2.x b/release-notes/VERSION-2.x
index 0b483c9..32c2069 100644
--- a/release-notes/VERSION-2.x
+++ b/release-notes/VERSION-2.x
@@ -10,6 +10,8 @@
   of type `UnwrappingBeanSerializer`
  (reported by Petar T)
 #2082: `FactoryBasedEnumDeserializer` should be cachable
+#2109: Canonical string for reference type is built incorrectly
+ (reported by svarzee@github)
 
 2.9.6 (12-Jun-2018)
 
diff --git a/src/main/java/com/fasterxml/jackson/databind/type/ReferenceType.java b/src/main/java/com/fasterxml/jackson/databind/type/ReferenceType.java
index 94aebb8..f9ac7a3 100644
--- a/src/main/java/com/fasterxml/jackson/databind/type/ReferenceType.java
+++ b/src/main/java/com/fasterxml/jackson/databind/type/ReferenceType.java
@@ -166,6 +166,7 @@
         sb.append(_class.getName());
         sb.append('<');
         sb.append(_referencedType.toCanonical());
+        sb.append('>');
         return sb.toString();
     }
 
diff --git a/src/test/java/com/fasterxml/jackson/databind/type/TestTypeFactory.java b/src/test/java/com/fasterxml/jackson/databind/type/TestTypeFactory.java
index d1256b8..60bcee8 100644
--- a/src/test/java/com/fasterxml/jackson/databind/type/TestTypeFactory.java
+++ b/src/test/java/com/fasterxml/jackson/databind/type/TestTypeFactory.java
@@ -232,8 +232,14 @@
                 can);
         assertEquals(t, tf.constructFromCanonical(can));
 
-        // [databind#1941]: allow "raw" types too
+        // [databind#2109]: also ReferenceTypes
+        t = tf.constructType(new TypeReference<AtomicReference<Long>>() { });
+        can = t.toCanonical();
+        assertEquals("java.util.concurrent.atomic.AtomicReference<java.lang.Long>",
+                can);
+        assertEquals(t, tf.constructFromCanonical(can));
 
+        // [databind#1941]: allow "raw" types too
         t = tf.constructFromCanonical("java.util.List");
         assertEquals(List.class, t.getRawClass());
         assertEquals(CollectionType.class, t.getClass());