Implement [JACKSON-802]
diff --git a/release-notes/VERSION b/release-notes/VERSION
index 90924b8..ac68299 100644
--- a/release-notes/VERSION
+++ b/release-notes/VERSION
@@ -13,6 +13,8 @@
(reported by Erik G)
* [JACKSON-794]: JDK 7 has new property for Exceptions ("suppressable"),
needs to be ignored during deserialization
+ * [JACKSON-802]: Improvements to class loading to use both contextual
+ class loader and Class.forName, as necessary
* [JACKSON-803]: Problems with Smile, parsing of long names
(reported by D Lam)
diff --git a/src/mapper/java/org/codehaus/jackson/map/jsontype/impl/ClassNameIdResolver.java b/src/mapper/java/org/codehaus/jackson/map/jsontype/impl/ClassNameIdResolver.java
index c8ddace..c9fd65e 100644
--- a/src/mapper/java/org/codehaus/jackson/map/jsontype/impl/ClassNameIdResolver.java
+++ b/src/mapper/java/org/codehaus/jackson/map/jsontype/impl/ClassNameIdResolver.java
@@ -51,12 +51,7 @@
return t;
}
try {
- /* [JACKSON-350]: Default Class.forName() won't work too well; context class loader
- * seems like slightly better choice
- */
-// Class<?> cls = Class.forName(id);
- ClassLoader loader = Thread.currentThread().getContextClassLoader();
- Class<?> cls = Class.forName(id, true, loader);
+ Class<?> cls = ClassUtil.findClass(id);
return _typeFactory.constructSpecializedType(_baseType, cls);
} catch (ClassNotFoundException e) {
throw new IllegalArgumentException("Invalid type id '"+id+"' (for id type 'Id.class'): no such class found");
diff --git a/src/mapper/java/org/codehaus/jackson/map/type/TypeParser.java b/src/mapper/java/org/codehaus/jackson/map/type/TypeParser.java
index 5d8a68f..f53ccb2 100644
--- a/src/mapper/java/org/codehaus/jackson/map/type/TypeParser.java
+++ b/src/mapper/java/org/codehaus/jackson/map/type/TypeParser.java
@@ -3,6 +3,7 @@
import java.util.*;
import org.codehaus.jackson.type.JavaType;
+import org.codehaus.jackson.map.util.ClassUtil;
/**
* Simple recursive-descent parser for parsing canonical {@link JavaType}
@@ -70,12 +71,7 @@
protected Class<?> findClass(String className, MyTokenizer tokens)
{
try {
- /* [JACKSON-350]: Default Class.forName() won't work too well; context class loader
- * seems like slightly better choice
- */
-// return Class.forName(className);
- ClassLoader loader = Thread.currentThread().getContextClassLoader();
- return Class.forName(className, true, loader);
+ return ClassUtil.findClass(className);
} catch (Exception e) {
if (e instanceof RuntimeException) {
throw (RuntimeException) e;
diff --git a/src/mapper/java/org/codehaus/jackson/map/util/ClassUtil.java b/src/mapper/java/org/codehaus/jackson/map/util/ClassUtil.java
index a58d486..7b04299 100644
--- a/src/mapper/java/org/codehaus/jackson/map/util/ClassUtil.java
+++ b/src/mapper/java/org/codehaus/jackson/map/util/ClassUtil.java
@@ -211,6 +211,50 @@
(Class<?>) classOrInstance : classOrInstance.getClass();
return cls.getName();
}
+
+ /*
+ /**********************************************************
+ /* Class loading
+ /**********************************************************
+ */
+
+ public static Class<?> findClass(String className) throws ClassNotFoundException
+ {
+ // [JACKSON-597]: support primitive types (and void)
+ if (className.indexOf('.') < 0) {
+ if ("int".equals(className)) return Integer.TYPE;
+ if ("long".equals(className)) return Long.TYPE;
+ if ("float".equals(className)) return Float.TYPE;
+ if ("double".equals(className)) return Double.TYPE;
+ if ("boolean".equals(className)) return Boolean.TYPE;
+ if ("byte".equals(className)) return Byte.TYPE;
+ if ("char".equals(className)) return Character.TYPE;
+ if ("short".equals(className)) return Short.TYPE;
+ if ("void".equals(className)) return Void.TYPE;
+ }
+ // Two-phase lookup: first using context ClassLoader; then default
+ Throwable prob = null;
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+
+ if (loader != null) {
+ try {
+ return Class.forName(className, true, loader);
+ } catch (Exception e) {
+ prob = getRootCause(e);
+ }
+ }
+ try {
+ return Class.forName(className);
+ } catch (Exception e) {
+ if (prob == null) {
+ prob = getRootCause(e);
+ }
+ }
+ if (prob instanceof RuntimeException) {
+ throw (RuntimeException) prob;
+ }
+ throw new ClassNotFoundException(prob.getMessage(), prob);
+ }
/*
/**********************************************************