From c47fd95d04ec3c961b2119528d3f02a11ec7aa74 Mon Sep 17 00:00:00 2001 From: Gunnar Morling Date: Tue, 5 Jul 2016 21:46:45 +0200 Subject: [PATCH] #801 Trying to load mapper implementation types via the mapper interface's loader first --- .../java/org/mapstruct/factory/Mappers.java | 71 ++++++++++++------- 1 file changed, 46 insertions(+), 25 deletions(-) diff --git a/core-common/src/main/java/org/mapstruct/factory/Mappers.java b/core-common/src/main/java/org/mapstruct/factory/Mappers.java index 8fc3ea35b..1d188ba8a 100644 --- a/core-common/src/main/java/org/mapstruct/factory/Mappers.java +++ b/core-common/src/main/java/org/mapstruct/factory/Mappers.java @@ -18,10 +18,12 @@ */ package org.mapstruct.factory; -import org.mapstruct.Mapper; - +import java.util.ArrayList; +import java.util.List; import java.util.ServiceLoader; +import org.mapstruct.Mapper; + /** * Factory for obtaining mapper instances if no explicit component model such as CDI is configured via * {@link Mapper#componentModel()}. @@ -62,39 +64,58 @@ public class Mappers { */ public static T getMapper(Class clazz) { try { + List classLoaders = new ArrayList( 3 ); + classLoaders.add( clazz.getClassLoader() ); - // Check that - // - clazz is an interface - // - the implementation type implements clazz - // - clazz is annotated with @Mapper - // - // Use privileged action - ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - - if ( classLoader == null ) { - classLoader = Mappers.class.getClassLoader(); + if ( Thread.currentThread().getContextClassLoader() != null ) { + classLoaders.add( Thread.currentThread().getContextClassLoader() ); } - try { - @SuppressWarnings("unchecked") - T mapper = (T) classLoader.loadClass( clazz.getName() + IMPLEMENTATION_SUFFIX ).newInstance(); + classLoaders.add( Mappers.class.getClassLoader() ); + + return getMapper( clazz, classLoaders ); + } + catch ( ClassNotFoundException e ) { + throw new RuntimeException( e ); + } + } + + private static T getMapper( + Class mapperType, Iterable classLoaders) throws ClassNotFoundException { + + for ( ClassLoader classLoader : classLoaders ) { + T mapper = doGetMapper( mapperType, classLoader ); + if ( mapper != null ) { return mapper; } - catch (ClassNotFoundException e) { - ServiceLoader loader = ServiceLoader.load( clazz, classLoader ); + } - if ( loader != null ) { - for ( T mapper : loader ) { - if ( mapper != null ) { - return mapper; - } + throw new ClassNotFoundException("Cannot find implementation for " + mapperType.getName() ); + } + + private static T doGetMapper(Class clazz, ClassLoader classLoader) { + try { + @SuppressWarnings("unchecked") + T mapper = (T) classLoader.loadClass( clazz.getName() + IMPLEMENTATION_SUFFIX ).newInstance(); + return mapper; + } + catch (ClassNotFoundException e) { + ServiceLoader loader = ServiceLoader.load( clazz, classLoader ); + + if ( loader != null ) { + for ( T mapper : loader ) { + if ( mapper != null ) { + return mapper; } } - - throw new ClassNotFoundException("Cannot find implementation for " + clazz.getName()); } + + return null; } - catch ( Exception e ) { + catch (InstantiationException e) { + throw new RuntimeException( e ); + } + catch (IllegalAccessException e) { throw new RuntimeException( e ); } }