From 3858853f649949c8eba9302d1c42d63d017b260f Mon Sep 17 00:00:00 2001 From: Charles Allen Date: Thu, 7 May 2015 12:56:37 -0700 Subject: [PATCH 1/2] Add handlings for classes which are available in `Thread.currentThread().getContextClassLoader()` --- .../databind/introspect/AnnotatedClass.java | 49 +++++++++++++++++-- 1 file changed, 46 insertions(+), 3 deletions(-) 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 fa379b104d..bcc5bb79a4 100644 --- a/src/main/java/com/fasterxml/jackson/databind/introspect/AnnotatedClass.java +++ b/src/main/java/com/fasterxml/jackson/databind/introspect/AnnotatedClass.java @@ -378,7 +378,30 @@ private void resolveCreators() List creatorMethods = null; // Then static methods which are potential factory methods - for (Method m : _class.getDeclaredMethods()) { + + Method[] classMethods; + try{ + classMethods = _class.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(_class.getName()); + } + catch (ClassNotFoundException e) { + //ex.addSuppressed(e); Not until 1.7 + throw ex; + } + classMethods = contextClass.getDeclaredMethods(); // Cross fingers + } + + for (Method m : classMethods) { if (!Modifier.isStatic(m.getModifiers())) { continue; } @@ -596,9 +619,29 @@ protected void _addMemberMethods(Class cls, AnnotatedMethodMap methods, if (cls == null) { // just so caller need not check when passing super-class return; } - + Method[] classMethods; + try{ + classMethods = 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) { + //ex.addSuppressed(e); Not until 1.7 + throw ex; + } + classMethods = contextClass.getDeclaredMethods(); // Cross fingers + } // then methods from the class itself - for (Method m : cls.getDeclaredMethods()) { + for (Method m : classMethods) { if (!_isIncludableMemberMethod(m)) { continue; } From 7db1f44069bbcac9d884d829f8052a89b5ec271b Mon Sep 17 00:00:00 2001 From: Cowtowncoder Date: Fri, 8 May 2015 15:20:18 -0700 Subject: [PATCH 2/2] Update release notes wrt #785, minor refactoring --- release-notes/CREDITS | 5 ++ release-notes/VERSION | 4 +- .../databind/introspect/AnnotatedClass.java | 90 ++++++++----------- 3 files changed, 46 insertions(+), 53 deletions(-) diff --git a/release-notes/CREDITS b/release-notes/CREDITS index 1fc8c1cc8d..6e7cf1c82c 100644 --- a/release-notes/CREDITS +++ b/release-notes/CREDITS @@ -157,3 +157,8 @@ Eugene Lukash Fernando Otero (zeitos@github) * Contributed fix for #610: Problem with forward reference in hierarchies (2.4.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 61681f4ea3..1406f85938 100644 --- a/release-notes/VERSION +++ b/release-notes/VERSION @@ -4,10 +4,12 @@ Project: jackson-databind === Releases === ------------------------------------------------------------------------ -2.4.7 (not yet released) +2.4.6.1 (not yet released) #676: Deserialization of class with generic collection inside depends on how is was deserialized first time +#785: Add handlings for classes which are available in `Thread.currentThread().getContextClassLoader()` + (contributed by Charles A) 2.4.6 (23-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 bcc5bb79a4..c4c410b457 100644 --- a/src/main/java/com/fasterxml/jackson/databind/introspect/AnnotatedClass.java +++ b/src/main/java/com/fasterxml/jackson/databind/introspect/AnnotatedClass.java @@ -378,30 +378,7 @@ private void resolveCreators() List creatorMethods = null; // Then static methods which are potential factory methods - - Method[] classMethods; - try{ - classMethods = _class.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(_class.getName()); - } - catch (ClassNotFoundException e) { - //ex.addSuppressed(e); Not until 1.7 - throw ex; - } - classMethods = contextClass.getDeclaredMethods(); // Cross fingers - } - - for (Method m : classMethods) { + for (Method m : _findClassMethods(_class)) { if (!Modifier.isStatic(m.getModifiers())) { continue; } @@ -432,7 +409,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) @@ -619,29 +596,8 @@ protected void _addMemberMethods(Class cls, AnnotatedMethodMap methods, if (cls == null) { // just so caller need not check when passing super-class return; } - Method[] classMethods; - try{ - classMethods = 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) { - //ex.addSuppressed(e); Not until 1.7 - throw ex; - } - classMethods = contextClass.getDeclaredMethods(); // Cross fingers - } // then methods from the class itself - for (Method m : classMethods) { + for (Method m : _findClassMethods(cls)) { if (!_isIncludableMemberMethod(m)) { continue; } @@ -1056,11 +1012,41 @@ protected void _addMixUnders(Method src, AnnotatedMethod target) { _addAnnotationsIfNotPresent(target, src.getDeclaredAnnotations()); } - private final boolean _isAnnotationBundle(Annotation ann) - { - return (_annotationIntrospector != null) && _annotationIntrospector.isAnnotationBundle(ann); - } - + 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