diff --git a/release-notes/CREDITS b/release-notes/CREDITS index ce0cae00d3..9e62a52bb2 100644 --- a/release-notes/CREDITS +++ b/release-notes/CREDITS @@ -245,3 +245,8 @@ Andrew Duckett (andrewduckett@github) * Reported #771: Annotation bundles ignored when added to Mixin (2.5.4) +Charles Allen: + * Contributed #785: Add handlings for classes which are available in + `Thread.currentThread().getContextClassLoader()` + (2.5.4) + diff --git a/release-notes/VERSION b/release-notes/VERSION index a5b592942b..18c56e8d27 100644 --- a/release-notes/VERSION +++ b/release-notes/VERSION @@ -13,6 +13,8 @@ Project: jackson-databind (reported by Andrew D) #774: NPE from SqlDateSerializer as _useTimestamp is not checked for being null (reported by mrowkow@github) +#785: Add handlings for classes which are available in `Thread.currentThread().getContextClassLoader()` + (contributed by Charles A) - Fix handling of Enums wrt JSON Schema, when 'toString()' used for serialization 2.5.3 (24-Apr-2015) diff --git a/src/main/java/com/fasterxml/jackson/databind/introspect/AnnotatedClass.java b/src/main/java/com/fasterxml/jackson/databind/introspect/AnnotatedClass.java index 0473a11352..019b7be334 100644 --- a/src/main/java/com/fasterxml/jackson/databind/introspect/AnnotatedClass.java +++ b/src/main/java/com/fasterxml/jackson/databind/introspect/AnnotatedClass.java @@ -380,7 +380,7 @@ private void resolveCreators() List creatorMethods = null; // Then static methods which are potential factory methods - for (Method m : _class.getDeclaredMethods()) { + for (Method m : _findClassMethods(_class)) { if (!Modifier.isStatic(m.getModifiers())) { continue; } @@ -411,7 +411,7 @@ private void resolveCreators() } _creatorsResolved = true; } - + /** * Method for resolving member method information: aggregating all non-static methods * and combining annotations (to implement method-annotation inheritance) @@ -598,9 +598,8 @@ protected void _addMemberMethods(Class cls, AnnotatedMethodMap methods, if (cls == null) { // just so caller need not check when passing super-class return; } - // then methods from the class itself - for (Method m : cls.getDeclaredMethods()) { + for (Method m : _findClassMethods(cls)) { if (!_isIncludableMemberMethod(m)) { continue; } @@ -1016,6 +1015,37 @@ private final boolean _isAnnotationBundle(Annotation ann) { return (_annotationIntrospector != null) && _annotationIntrospector.isAnnotationBundle(ann); } + /** + * Helper method that gets methods declared in given class; usually a simple thing, + * but sometimes (as per [databind#785]) more complicated, depending on classloader + * setup. + * + * @since 2.4.7 + */ + protected Method[] _findClassMethods(Class cls) + { + try { + return cls.getDeclaredMethods(); + } catch (final NoClassDefFoundError ex) { + // One of the methods had a class that was not found in the cls.getClassLoader. + // Maybe the developer was nice and has a different class loader for this context. + final ClassLoader loader = Thread.currentThread().getContextClassLoader(); + if(loader == null){ + // Nope... this is going to end poorly + throw ex; + } + final Class contextClass; + try { + contextClass = loader.loadClass(cls.getName()); + } catch (ClassNotFoundException e) { + // !!! TODO: 08-May-2015, tatu: Chain appropriately once we have JDK7 as baseline + //ex.addSuppressed(e); Not until 1.7 + throw ex; + } + return contextClass.getDeclaredMethods(); // Cross fingers + } + } + /* /********************************************************** /* Other methods