You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tamaya.apache.org by an...@apache.org on 2015/06/14 00:18:39 UTC

[1/2] incubator-tamaya git commit: Moved extension into internal package, since extension is not meant for user access.

Repository: incubator-tamaya
Updated Branches:
  refs/heads/master fc155997c -> 4d5609848


Moved extension into internal package, since extension is not meant for user access.


Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/commit/eef4efe6
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/tree/eef4efe6
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/diff/eef4efe6

Branch: refs/heads/master
Commit: eef4efe63668372a3583eab5dcc103a1e20b71a2
Parents: fc15599
Author: Anatole Tresch <at...@java.net>
Authored: Sun Jun 14 00:00:36 2015 +0200
Committer: Anatole Tresch <at...@java.net>
Committed: Sun Jun 14 00:00:36 2015 +0200

----------------------------------------------------------------------
 .../integration/cdi/ConfigurationExtension.java | 79 --------------------
 .../cdi/internal/ConfigurationExtension.java    | 79 ++++++++++++++++++++
 .../javax.enterprise.inject.spi.Extension       |  2 +-
 3 files changed, 80 insertions(+), 80 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/eef4efe6/sandbox/integration/cdi/src/main/java/org/apache/tamaya/integration/cdi/ConfigurationExtension.java
----------------------------------------------------------------------
diff --git a/sandbox/integration/cdi/src/main/java/org/apache/tamaya/integration/cdi/ConfigurationExtension.java b/sandbox/integration/cdi/src/main/java/org/apache/tamaya/integration/cdi/ConfigurationExtension.java
deleted file mode 100644
index 2e1473a..0000000
--- a/sandbox/integration/cdi/src/main/java/org/apache/tamaya/integration/cdi/ConfigurationExtension.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.tamaya.integration.cdi;
-
-import org.apache.tamaya.core.internal.inject.ConfigurationInjector;
-import org.apache.tamaya.core.internal.inject.ConfiguredType;
-
-import javax.enterprise.context.spi.CreationalContext;
-import javax.enterprise.event.Observes;
-import javax.enterprise.inject.Vetoed;
-import javax.enterprise.inject.spi.*;
-import java.util.*;
-
-/**
- * CDI portable extension that integrates {@link org.apache.tamaya.core.internal.inject.ConfigurationInjector}
- * with CDI by adding configuration features to CDI (config enable CDI beans).
- */
-@Vetoed
-public final class ConfigurationExtension implements Extension {
-
-    public <T> void initializeConfiguredFields(final @Observes ProcessInjectionTarget<T> pit) {
-        final AnnotatedType<T> at = pit.getAnnotatedType();
-        if (!ConfiguredType.isConfigured(at.getJavaClass())) {
-            return;
-        }
-        final InjectionTarget<T> it = pit.getInjectionTarget();
-        InjectionTarget<T> wrapped = new InjectionTarget<T>() {
-            @Override
-            public void inject(T instance, CreationalContext<T> ctx) {
-                it.inject(instance, ctx);
-                ConfigurationInjector.configure(instance);
-            }
-
-            @Override
-            public void postConstruct(T instance) {
-                it.postConstruct(instance);
-            }
-
-            @Override
-            public void preDestroy(T instance) {
-                it.dispose(instance);
-            }
-
-            @Override
-            public void dispose(T instance) {
-                it.dispose(instance);
-            }
-
-            @Override
-            public Set<InjectionPoint> getInjectionPoints() {
-                return it.getInjectionPoints();
-            }
-
-            @Override
-            public T produce(CreationalContext<T> ctx) {
-                return it.produce(ctx);
-            }
-        };
-        pit.setInjectionTarget(wrapped);
-    }
-
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/eef4efe6/sandbox/integration/cdi/src/main/java/org/apache/tamaya/integration/cdi/internal/ConfigurationExtension.java
----------------------------------------------------------------------
diff --git a/sandbox/integration/cdi/src/main/java/org/apache/tamaya/integration/cdi/internal/ConfigurationExtension.java b/sandbox/integration/cdi/src/main/java/org/apache/tamaya/integration/cdi/internal/ConfigurationExtension.java
new file mode 100644
index 0000000..cdc98a6
--- /dev/null
+++ b/sandbox/integration/cdi/src/main/java/org/apache/tamaya/integration/cdi/internal/ConfigurationExtension.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.integration.cdi.internal;
+
+import org.apache.tamaya.core.internal.inject.ConfigurationInjector;
+import org.apache.tamaya.core.internal.inject.ConfiguredType;
+
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.Vetoed;
+import javax.enterprise.inject.spi.*;
+import java.util.*;
+
+/**
+ * CDI portable extension that integrates {@link org.apache.tamaya.core.internal.inject.ConfigurationInjector}
+ * with CDI by adding configuration features to CDI (config enable CDI beans).
+ */
+@Vetoed
+public final class ConfigurationExtension implements Extension {
+
+    public <T> void initializeConfiguredFields(final @Observes ProcessInjectionTarget<T> pit) {
+        final AnnotatedType<T> at = pit.getAnnotatedType();
+        if (!ConfiguredType.isConfigured(at.getJavaClass())) {
+            return;
+        }
+        final InjectionTarget<T> it = pit.getInjectionTarget();
+        InjectionTarget<T> wrapped = new InjectionTarget<T>() {
+            @Override
+            public void inject(T instance, CreationalContext<T> ctx) {
+                it.inject(instance, ctx);
+                ConfigurationInjector.configure(instance);
+            }
+
+            @Override
+            public void postConstruct(T instance) {
+                it.postConstruct(instance);
+            }
+
+            @Override
+            public void preDestroy(T instance) {
+                it.dispose(instance);
+            }
+
+            @Override
+            public void dispose(T instance) {
+                it.dispose(instance);
+            }
+
+            @Override
+            public Set<InjectionPoint> getInjectionPoints() {
+                return it.getInjectionPoints();
+            }
+
+            @Override
+            public T produce(CreationalContext<T> ctx) {
+                return it.produce(ctx);
+            }
+        };
+        pit.setInjectionTarget(wrapped);
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/eef4efe6/sandbox/integration/cdi/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
----------------------------------------------------------------------
diff --git a/sandbox/integration/cdi/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension b/sandbox/integration/cdi/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
index 2249aca..3b909e7 100644
--- a/sandbox/integration/cdi/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
+++ b/sandbox/integration/cdi/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
@@ -16,4 +16,4 @@
 # specific language governing permissions and limitations
 # under the License.
 #
-org.apache.tamaya.integration.cdi.ConfigurationExtension
+org.apache.tamaya.integration.cdi.internal.ConfigurationExtension


[2/2] incubator-tamaya git commit: TAMAYA-74 Added support for type narowwing on property conversion.

Posted by an...@apache.org.
TAMAYA-74 Added support for type narowwing on property conversion.


Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/commit/4d560984
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/tree/4d560984
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/diff/4d560984

Branch: refs/heads/master
Commit: 4d560984822e4ccc0b8bae0b00a98e278518a39e
Parents: eef4efe
Author: Anatole Tresch <at...@java.net>
Authored: Sun Jun 14 00:17:03 2015 +0200
Committer: Anatole Tresch <at...@java.net>
Committed: Sun Jun 14 00:17:03 2015 +0200

----------------------------------------------------------------------
 .../core/internal/DefaultServiceContext.java    |  21 ++-
 .../core/internal/PropertyConverterManager.java | 186 ++++++++++++++-----
 .../java/org/apache/tamaya/core/internal/A.java |  29 +++
 .../java/org/apache/tamaya/core/internal/B.java |  29 +++
 .../java/org/apache/tamaya/core/internal/C.java |  56 ++++++
 .../tamaya/core/internal/CTestConverter.java    |  31 ++++
 .../internal/PropertyConverterManagerTest.java  |  85 +++++++++
 .../org.apache.tamaya.spi.PropertyConverter     |  19 ++
 .../core/internal/DefaultServiceContext.java    |  20 +-
 .../core/internal/PropertyConverterManager.java | 131 ++++++++++---
 .../java/org/apache/tamaya/core/internal/A.java |  29 +++
 .../java/org/apache/tamaya/core/internal/B.java |  29 +++
 .../java/org/apache/tamaya/core/internal/C.java |  56 ++++++
 .../tamaya/core/internal/CTestConverter.java    |  31 ++++
 .../internal/PropertyConverterManagerTest.java  |  85 +++++++++
 .../org.apache.tamaya.spi.PropertyConverter     |  19 ++
 16 files changed, 778 insertions(+), 78 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/4d560984/java7/core/src/main/java/org/apache/tamaya/core/internal/DefaultServiceContext.java
----------------------------------------------------------------------
diff --git a/java7/core/src/main/java/org/apache/tamaya/core/internal/DefaultServiceContext.java b/java7/core/src/main/java/org/apache/tamaya/core/internal/DefaultServiceContext.java
index 2e59fa2..15bbcef 100644
--- a/java7/core/src/main/java/org/apache/tamaya/core/internal/DefaultServiceContext.java
+++ b/java7/core/src/main/java/org/apache/tamaya/core/internal/DefaultServiceContext.java
@@ -90,6 +90,20 @@ public final class DefaultServiceContext implements ServiceContext {
         return previousServices != null ? previousServices : services;
     }
 
+    /**
+     * Checks the given instance for a @Priority annotation. If present the annotation's value s evaluated. If no such
+     * annotation is present, a default priority is returned (1);
+     * @param o the instance, not null.
+     * @return a priority, by default 1.
+     */
+    public static int getPriority(Object o){
+        int prio = 1; //X TODO discuss default priority
+        Priority priority = o.getClass().getAnnotation(Priority.class);
+        if (priority != null) {
+            prio = priority.value();
+        }
+        return prio;
+    }
 
     /**
      * @param services to scan
@@ -111,12 +125,7 @@ public final class DefaultServiceContext implements ServiceContext {
         T highestService = null;
 
         for (T service : services) {
-            int prio = 1; //X TODO discuss default priority
-            Priority priority = service.getClass().getAnnotation(Priority.class);
-            if (priority != null) {
-                prio = priority.value();
-            }
-
+            int prio = getPriority(service);
             if (highestPriority == null || highestPriority < prio) {
                 highestService = service;
                 highestPriorityServiceCount = 1;

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/4d560984/java7/core/src/main/java/org/apache/tamaya/core/internal/PropertyConverterManager.java
----------------------------------------------------------------------
diff --git a/java7/core/src/main/java/org/apache/tamaya/core/internal/PropertyConverterManager.java b/java7/core/src/main/java/org/apache/tamaya/core/internal/PropertyConverterManager.java
index 31a05b2..7fe6b11 100644
--- a/java7/core/src/main/java/org/apache/tamaya/core/internal/PropertyConverterManager.java
+++ b/java7/core/src/main/java/org/apache/tamaya/core/internal/PropertyConverterManager.java
@@ -24,6 +24,7 @@ import java.lang.reflect.Modifier;
 import java.lang.reflect.Type;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -45,12 +46,38 @@ import org.apache.tamaya.spi.ServiceContextManager;
  * This class is thread-safe.
  */
 public class PropertyConverterManager {
-    /** The logger used. */
+    /**
+     * The logger used.
+     */
     private static final Logger LOG = Logger.getLogger(PropertyConverterManager.class.getName());
-    /** The registered converters. */
+    /**
+     * The registered converters.
+     */
     private Map<TypeLiteral<?>, List<PropertyConverter<?>>> converters = new ConcurrentHashMap<>();
-    /** The lock used. */
+    /**
+     * The transitive converters.
+     */
+    private Map<TypeLiteral<?>, List<PropertyConverter<?>>> transitiveConverters = new ConcurrentHashMap<>();
+    /**
+     * The lock used.
+     */
     private ReadWriteLock lock = new ReentrantReadWriteLock();
+
+    private static final Comparator<Object> PRIORITY_COMPARATOR = new Comparator<Object>() {
+
+        @Override
+        public int compare(Object o1, Object o2) {
+            int prio = DefaultServiceContext.getPriority(o1) - DefaultServiceContext.getPriority(o2);
+            if (prio < 0) {
+                return 1;
+            } else if (prio > 0) {
+                return -1;
+            } else {
+                return o1.getClass().getSimpleName().compareTo(o2.getClass().getSimpleName());
+            }
+        }
+    };
+
     /**
      * Constructor.
      */
@@ -68,7 +95,7 @@ public class PropertyConverterManager {
      * Registers the default converters provided out of the box.
      */
     protected void initConverters() {
-        for(PropertyConverter conv: ServiceContextManager.getServiceContext().getServices(PropertyConverter.class)){
+        for (PropertyConverter conv : ServiceContextManager.getServiceContext().getServices(PropertyConverter.class)) {
             Type type = TypeLiteral.getGenericInterfaceTypeParameters(conv.getClass(), PropertyConverter.class)[0];
             register(TypeLiteral.of(type), conv);
         }
@@ -86,13 +113,48 @@ public class PropertyConverterManager {
         Lock writeLock = lock.writeLock();
         try {
             writeLock.lock();
-            List<PropertyConverter<T>> converters = List.class.cast(this.converters.get(targetType));
+            List converters = List.class.cast(this.converters.get(targetType));
             List<PropertyConverter<?>> newConverters = new ArrayList<>();
             if (converters != null) {
                 newConverters.addAll(converters);
             }
             newConverters.add(converter);
+            Collections.sort(newConverters, PRIORITY_COMPARATOR);
             this.converters.put(targetType, Collections.unmodifiableList(newConverters));
+            // evaluate transitive closure for all inherited supertypes and implemented interfaces
+            // direct implemented interfaces
+            for (Class<?> ifaceType : targetType.getRawType().getInterfaces()) {
+                converters = List.class.cast(this.transitiveConverters.get(ifaceType));
+                newConverters = new ArrayList<>();
+                if (converters != null) {
+                    newConverters.addAll(converters);
+                }
+                newConverters.add(converter);
+                Collections.sort(newConverters, PRIORITY_COMPARATOR);
+                this.transitiveConverters.put(TypeLiteral.of(ifaceType), Collections.unmodifiableList(newConverters));
+            }
+            Class<?> superClass = targetType.getRawType().getSuperclass();
+            while (superClass != null && !superClass.equals(Object.class)) {
+                converters = List.class.cast(this.transitiveConverters.get(superClass));
+                newConverters = new ArrayList<>();
+                if (converters != null) {
+                    newConverters.addAll(converters);
+                }
+                newConverters.add(converter);
+                Collections.sort(newConverters, PRIORITY_COMPARATOR);
+                this.transitiveConverters.put(TypeLiteral.of(superClass), Collections.unmodifiableList(newConverters));
+                for (Class<?> ifaceType : superClass.getInterfaces()) {
+                    converters = List.class.cast(this.transitiveConverters.get(ifaceType));
+                    newConverters = new ArrayList<>();
+                    if (converters != null) {
+                        newConverters.addAll(converters);
+                    }
+                    newConverters.add(converter);
+                    Collections.sort(newConverters, PRIORITY_COMPARATOR);
+                    this.transitiveConverters.put(TypeLiteral.of(ifaceType), Collections.unmodifiableList(newConverters));
+                }
+                superClass = superClass.getSuperclass();
+            }
         } finally {
             writeLock.unlock();
         }
@@ -105,8 +167,10 @@ public class PropertyConverterManager {
      * @return true, if a converter for the given type is registered, or a default one can be created.
      */
     public boolean isTargetTypeSupported(TypeLiteral<?> targetType) {
-        return converters.containsKey(targetType)
-                || createDefaultPropertyConverter(targetType) != null;
+        if (converters.containsKey(targetType) || transitiveConverters.containsKey(targetType)) {
+            return true;
+        }
+        return createDefaultPropertyConverter(targetType) != null;
     }
 
     /**
@@ -130,7 +194,26 @@ public class PropertyConverterManager {
     /**
      * Get the list of all current registered converters for the given target type.
      * If not converters are registered, they component tries to create and register a dynamic
-     * converter based on String costructor or static factory methods available.
+     * converter based on String costructor or static factory methods available.<br/>
+     * The converters provided are of the following type and returned in the following order:
+     * <ul>
+     *     <li>Converters mapped explicitly to the required target type are returned first, ordered
+     *     by decreasing priority. This means, if explicit converters are registered these are used
+     *     primarly for converting a value.</li>
+     *     <li>The target type of each explicitly registered converter also can be transitively mapped to
+     *     1) all directly implemented interfaces, 2) all its superclasses (except Object), 3) all the interfaces
+     *     implemented by its superclasses. These groups of transitive converters is returned similarly in the
+     *     order as mentioned, whereas also here a priority based decreasing ordering is applied.</li>
+     *     <li>java.lang wrapper classes and native types are automatically mapped.</li>
+     *     <li>If no explicit converters are registered, for Enum types a default implementation is provided that
+     *     compares the configuration values with the different enum members defined (cases sensitive mapping).</li>
+     * </ul>
+     *
+     * So given that list above directly registered mappings always are tried first, before any transitive mapping
+     * should be used. Also in all cases @Priority annotations are honored for ordering of the converters in place.
+     * Transitive conversion is supported for all directly implemented interfaces (including inherited ones) and
+     * the inheritance hierarchy (exception Object). Superinterfaces of implemented interfaces are ignored.
+     *
      *
      * @param targetType the target type, not null.
      * @param <T>        the type class
@@ -139,7 +222,9 @@ public class PropertyConverterManager {
      */
     public <T> List<PropertyConverter<T>> getPropertyConverters(TypeLiteral<T> targetType) {
         Lock readLock = lock.readLock();
+        List<PropertyConverter<T>> converterList = new ArrayList<>();
         List<PropertyConverter<T>> converters;
+        // direct mapped converters
         try {
             readLock.lock();
             converters = List.class.cast(this.converters.get(targetType));
@@ -147,10 +232,21 @@ public class PropertyConverterManager {
             readLock.unlock();
         }
         if (converters != null) {
-            return converters;
+            converterList.addAll(converters);
+        }
+        // transitive converter
+        try {
+            readLock.lock();
+            converters = List.class.cast(this.transitiveConverters.get(targetType));
+        } finally {
+            readLock.unlock();
+        }
+        if (converters != null) {
+            converterList.addAll(converters);
         }
+        // handling of java.lang wrapper classes
         TypeLiteral<T> boxedType = mapBoxedType(targetType);
-        if(boxedType!=null){
+        if (boxedType != null) {
             try {
                 readLock.lock();
                 converters = List.class.cast(this.converters.get(boxedType));
@@ -158,79 +254,83 @@ public class PropertyConverterManager {
                 readLock.unlock();
             }
             if (converters != null) {
-                return converters;
+                converterList.addAll(converters);
             }
         }
-        PropertyConverter<T> defaultConverter = createDefaultPropertyConverter(targetType);
-        if (defaultConverter != null) {
-            register(targetType, defaultConverter);
-            try {
-                readLock.lock();
-                converters = List.class.cast(this.converters.get(targetType));
-            } finally {
-                readLock.unlock();
+        if (converterList.isEmpty()) {
+            // adding any converters created on the fly, e.g. for enum types.
+            PropertyConverter<T> defaultConverter = createDefaultPropertyConverter(targetType);
+            if (defaultConverter != null) {
+                register(targetType, defaultConverter);
+                try {
+                    readLock.lock();
+                    converters = List.class.cast(this.converters.get(targetType));
+                } finally {
+                    readLock.unlock();
+                }
+            }
+            if (converters != null) {
+                converterList.addAll(converters);
             }
         }
-        if (converters != null) {
-            return converters;
-        }
-        return Collections.emptyList();
+        return converterList;
     }
 
     /**
      * Maps native types to the corresponding boxed types.
+     *
      * @param targetType the native type.
-     * @param <T> the type
+     * @param <T>        the type
      * @return the boxed type, or null.
      */
     private <T> TypeLiteral<T> mapBoxedType(TypeLiteral<T> targetType) {
         Type parameterType = targetType.getType();
-        if(parameterType == int.class){
+        if (parameterType == int.class) {
             return TypeLiteral.class.cast(TypeLiteral.of(Integer.class));
         }
-        if(parameterType == short.class){
+        if (parameterType == short.class) {
             return TypeLiteral.class.cast(TypeLiteral.of(Short.class));
         }
-        if(parameterType == byte.class){
+        if (parameterType == byte.class) {
             return TypeLiteral.class.cast(TypeLiteral.of(Byte.class));
         }
-        if(parameterType == long.class){
+        if (parameterType == long.class) {
             return TypeLiteral.class.cast(TypeLiteral.of(Long.class));
         }
-        if(parameterType == boolean.class){
+        if (parameterType == boolean.class) {
             return TypeLiteral.class.cast(TypeLiteral.of(Boolean.class));
         }
-        if(parameterType == char.class){
+        if (parameterType == char.class) {
             return TypeLiteral.class.cast(TypeLiteral.of(Character.class));
         }
-        if(parameterType == float.class){
+        if (parameterType == float.class) {
             return TypeLiteral.class.cast(TypeLiteral.of(Float.class));
         }
-        if(parameterType == double.class){
+        if (parameterType == double.class) {
             return TypeLiteral.class.cast(TypeLiteral.of(Double.class));
         }
-        if(parameterType == int[].class){
+        if (parameterType == int[].class) {
             return TypeLiteral.class.cast(TypeLiteral.of(Integer[].class));
         }
-        if(parameterType == short[].class){
+        if (parameterType == short[].class) {
             return TypeLiteral.class.cast(TypeLiteral.of(Short[].class));
         }
-        if(parameterType == byte[].class){
+        if (parameterType == byte[].class) {
             return TypeLiteral.class.cast(TypeLiteral.of(Byte[].class));
         }
-        if(parameterType == long[].class){
+        if (parameterType == long[].class) {
             return TypeLiteral.class.cast(TypeLiteral.of(Long[].class));
         }
-        if(parameterType == boolean.class){
+        if (parameterType == boolean.class) {
             return TypeLiteral.class.cast(TypeLiteral.of(Boolean.class));
         }
-        if(parameterType == char[].class){
+        if (parameterType == char[].class) {
             return TypeLiteral.class.cast(TypeLiteral.of(Character[].class));
         }
-        if(parameterType == float[].class){
+        if (parameterType == float[].class) {
             return TypeLiteral.class.cast(TypeLiteral.of(Float[].class));
         }
-        if(parameterType == double[].class){
+        if (parameterType == double[].class) {
             return TypeLiteral.class.cast(TypeLiteral.of(Double[].class));
         }
         return null;
@@ -244,7 +344,7 @@ public class PropertyConverterManager {
      * @return a new converter, or null.
      */
     protected <T> PropertyConverter<T> createDefaultPropertyConverter(final TypeLiteral<T> targetType) {
-        if(Enum.class.isAssignableFrom(targetType.getRawType())){
+        if (Enum.class.isAssignableFrom(targetType.getRawType())) {
             return new EnumConverter<T>(targetType.getRawType());
         }
         PropertyConverter<T> converter = null;
@@ -285,7 +385,7 @@ public class PropertyConverterManager {
                     }
                 };
             } catch (Exception e) {
-                LOG.finest("Failed to construct instance of type: " + targetType.getRawType().getName()+": " + e);
+                LOG.finest("Failed to construct instance of type: " + targetType.getRawType().getName() + ": " + e);
             }
         }
         return converter;
@@ -305,7 +405,7 @@ public class PropertyConverterManager {
                 m = type.getDeclaredMethod(name, String.class);
                 return m;
             } catch (NoSuchMethodException | RuntimeException e) {
-                LOG.finest("No such factory method found on type: " + type.getName()+", methodName: " + name);
+                LOG.finest("No such factory method found on type: " + type.getName() + ", methodName: " + name);
             }
         }
         return null;

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/4d560984/java7/core/src/test/java/org/apache/tamaya/core/internal/A.java
----------------------------------------------------------------------
diff --git a/java7/core/src/test/java/org/apache/tamaya/core/internal/A.java b/java7/core/src/test/java/org/apache/tamaya/core/internal/A.java
new file mode 100644
index 0000000..aa77a5d
--- /dev/null
+++ b/java7/core/src/test/java/org/apache/tamaya/core/internal/A.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.internal;
+
+/**
+ * Test class for testing transitively evaluated property converters.
+ */
+public class A implements AutoCloseable{
+    @Override
+    public void close() throws Exception {
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/4d560984/java7/core/src/test/java/org/apache/tamaya/core/internal/B.java
----------------------------------------------------------------------
diff --git a/java7/core/src/test/java/org/apache/tamaya/core/internal/B.java b/java7/core/src/test/java/org/apache/tamaya/core/internal/B.java
new file mode 100644
index 0000000..31bafb6
--- /dev/null
+++ b/java7/core/src/test/java/org/apache/tamaya/core/internal/B.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.internal;
+
+/**
+ * Test class for testing transitively evaluated property converters.
+ */
+public class B extends A implements Runnable{
+    @Override
+    public void run() {
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/4d560984/java7/core/src/test/java/org/apache/tamaya/core/internal/C.java
----------------------------------------------------------------------
diff --git a/java7/core/src/test/java/org/apache/tamaya/core/internal/C.java b/java7/core/src/test/java/org/apache/tamaya/core/internal/C.java
new file mode 100644
index 0000000..aad1ef9
--- /dev/null
+++ b/java7/core/src/test/java/org/apache/tamaya/core/internal/C.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.internal;
+
+import java.io.IOException;
+import java.nio.CharBuffer;
+
+/**
+ * Test class for testing transitively evaluated property converters.
+ */
+public class C extends B implements Readable{
+
+    private String inValue;
+
+    public C(String inValue){
+        this.inValue = inValue;
+    }
+
+    @Override
+    public int read(CharBuffer cb) throws IOException {
+        return 0;
+    }
+
+    /**
+     * Returns the input value, set on creation. Used for test assertion.
+     * @return the in value.
+     */
+    public String getInValue() {
+        return inValue;
+    }
+
+    @Override
+    public String toString() {
+        return "C{" +
+                "inValue='" + inValue + '\'' +
+                '}';
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/4d560984/java7/core/src/test/java/org/apache/tamaya/core/internal/CTestConverter.java
----------------------------------------------------------------------
diff --git a/java7/core/src/test/java/org/apache/tamaya/core/internal/CTestConverter.java b/java7/core/src/test/java/org/apache/tamaya/core/internal/CTestConverter.java
new file mode 100644
index 0000000..62b8c9d
--- /dev/null
+++ b/java7/core/src/test/java/org/apache/tamaya/core/internal/CTestConverter.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.internal;
+
+import org.apache.tamaya.spi.PropertyConverter;
+
+/**
+ * Created by Anatole on 13.06.2015.
+ */
+public class CTestConverter implements PropertyConverter<C>{
+    @Override
+    public C convert(String value) {
+        return new C(value);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/4d560984/java7/core/src/test/java/org/apache/tamaya/core/internal/PropertyConverterManagerTest.java
----------------------------------------------------------------------
diff --git a/java7/core/src/test/java/org/apache/tamaya/core/internal/PropertyConverterManagerTest.java b/java7/core/src/test/java/org/apache/tamaya/core/internal/PropertyConverterManagerTest.java
index bd9b97f..9ec6076 100644
--- a/java7/core/src/test/java/org/apache/tamaya/core/internal/PropertyConverterManagerTest.java
+++ b/java7/core/src/test/java/org/apache/tamaya/core/internal/PropertyConverterManagerTest.java
@@ -57,6 +57,90 @@ public class PropertyConverterManagerTest {
         assertThat(((MyType)result).getValue(), equalTo("IN"));
     }
 
+    @Test
+    public void testDirectConverterMapping(){
+        PropertyConverterManager manager = new PropertyConverterManager();
+        List<PropertyConverter<C>> converters = List.class.cast(manager.getPropertyConverters(TypeLiteral.of(C.class)));
+        assertThat(converters, hasSize(1));
+
+        PropertyConverter<C> converter = converters.get(0);
+        C result = converter.convert("testDirectConverterMapping");
+
+        assertThat(result, notNullValue());
+        assertThat(result, instanceOf(C.class));
+        assertThat(((C)result).getInValue(), equalTo("testDirectConverterMapping"));
+    }
+
+    @Test
+    public void testDirectSuperclassConverterMapping(){
+        PropertyConverterManager manager = new PropertyConverterManager();
+        List<PropertyConverter<B>> converters = List.class.cast(manager.getPropertyConverters(TypeLiteral.of(B.class)));
+        assertThat(converters, hasSize(1));
+
+        PropertyConverter<B> converter = converters.get(0);
+        B result = converter.convert("testDirectSuperclassConverterMapping");
+
+        assertThat(result, notNullValue());
+        assertThat(result, instanceOf(C.class));
+        assertThat(((C)result).getInValue(), equalTo("testDirectSuperclassConverterMapping"));
+    }
+
+    @Test
+    public void testTransitiveSuperclassConverterMapping(){
+        PropertyConverterManager manager = new PropertyConverterManager();
+        List<PropertyConverter<A>> converters = List.class.cast(manager.getPropertyConverters(TypeLiteral.of(A.class)));
+        assertThat(converters, hasSize(1));
+
+        PropertyConverter<A> converter = converters.get(0);
+        A result = converter.convert("testTransitiveSuperclassConverterMapping");
+
+        assertThat(result, notNullValue());
+        assertThat(result, instanceOf(C.class));
+        assertThat(((C)result).getInValue(), equalTo("testTransitiveSuperclassConverterMapping"));
+    }
+
+    @Test
+    public void testDirectInterfaceMapping(){
+        PropertyConverterManager manager = new PropertyConverterManager();
+        List<PropertyConverter<Readable>> converters = List.class.cast(manager.getPropertyConverters(TypeLiteral.of(Readable.class)));
+        assertThat(converters, hasSize(1));
+
+        PropertyConverter<Readable> converter = converters.get(0);
+        Readable result = converter.convert("testDirectInterfaceMapping");
+
+        assertThat(result, notNullValue());
+        assertThat(result, instanceOf(C.class));
+        assertThat(((C)result).getInValue(), equalTo("testDirectInterfaceMapping"));
+    }
+
+    @Test
+    public void testTransitiveInterfaceMapping1(){
+        PropertyConverterManager manager = new PropertyConverterManager();
+        List<PropertyConverter<Runnable>> converters = List.class.cast(manager.getPropertyConverters(TypeLiteral.of(Runnable.class)));
+        assertThat(converters, hasSize(1));
+
+        PropertyConverter<Runnable> converter = converters.get(0);
+        Runnable result = converter.convert("testTransitiveInterfaceMapping1");
+
+        assertThat(result, notNullValue());
+        assertThat(result, instanceOf(C.class));
+        assertThat(((C)result).getInValue(), equalTo("testTransitiveInterfaceMapping1"));
+    }
+
+    @Test
+    public void testTransitiveInterfaceMapping2(){
+        PropertyConverterManager manager = new PropertyConverterManager();
+        List<PropertyConverter<AutoCloseable>> converters = List.class.cast(manager.getPropertyConverters(TypeLiteral.of(AutoCloseable.class)));
+        assertThat(converters, hasSize(1));
+
+        PropertyConverter<AutoCloseable> converter = converters.get(0);
+        AutoCloseable result = converter.convert("testTransitiveInterfaceMapping2");
+
+        assertThat(result, notNullValue());
+        assertThat(result, instanceOf(C.class));
+        assertThat(((C)result).getInValue(), equalTo("testTransitiveInterfaceMapping2"));
+    }
+
     public static class MyType {
         private String typeValue;
 
@@ -73,4 +157,5 @@ public class PropertyConverterManagerTest {
         }
 
     }
+
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/4d560984/java7/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertyConverter
----------------------------------------------------------------------
diff --git a/java7/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertyConverter b/java7/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertyConverter
new file mode 100644
index 0000000..d039696
--- /dev/null
+++ b/java7/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertyConverter
@@ -0,0 +1,19 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy current the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+org.apache.tamaya.core.internal.CTestConverter
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/4d560984/java8/core/src/main/java/org/apache/tamaya/core/internal/DefaultServiceContext.java
----------------------------------------------------------------------
diff --git a/java8/core/src/main/java/org/apache/tamaya/core/internal/DefaultServiceContext.java b/java8/core/src/main/java/org/apache/tamaya/core/internal/DefaultServiceContext.java
index 42c928b..7315ef1 100644
--- a/java8/core/src/main/java/org/apache/tamaya/core/internal/DefaultServiceContext.java
+++ b/java8/core/src/main/java/org/apache/tamaya/core/internal/DefaultServiceContext.java
@@ -89,6 +89,20 @@ public final class DefaultServiceContext implements ServiceContext {
         return previousServices != null ? previousServices : services;
     }
 
+    /**
+     * Checks the given instance for a @Priority annotation. If present the annotation's value s evaluated. If no such
+     * annotation is present, a default priority is returned (1);
+     * @param o the instance, not null.
+     * @return a priority, by default 1.
+     */
+    public static int getPriority(Object o){
+        int prio = 1; //X TODO discuss default priority
+        Priority priority = o.getClass().getAnnotation(Priority.class);
+        if (priority != null) {
+            prio = priority.value();
+        }
+        return prio;
+    }
 
     /**
      * @param services to scan
@@ -110,11 +124,7 @@ public final class DefaultServiceContext implements ServiceContext {
         T highestService = null;
 
         for (T service : services) {
-            int prio = 1; //X TODO discuss default priority
-            Priority priority = service.getClass().getAnnotation(Priority.class);
-            if (priority != null) {
-                prio = priority.value();
-            }
+            int prio = getPriority(service);
 
             if (highestPriority == null || highestPriority < prio) {
                 highestService = service;

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/4d560984/java8/core/src/main/java/org/apache/tamaya/core/internal/PropertyConverterManager.java
----------------------------------------------------------------------
diff --git a/java8/core/src/main/java/org/apache/tamaya/core/internal/PropertyConverterManager.java b/java8/core/src/main/java/org/apache/tamaya/core/internal/PropertyConverterManager.java
index 333572e..3cb0656 100644
--- a/java8/core/src/main/java/org/apache/tamaya/core/internal/PropertyConverterManager.java
+++ b/java8/core/src/main/java/org/apache/tamaya/core/internal/PropertyConverterManager.java
@@ -22,12 +22,7 @@ import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
+import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.StampedLock;
@@ -48,8 +43,23 @@ public class PropertyConverterManager {
     private static final Logger LOG = Logger.getLogger(PropertyConverterManager.class.getName());
     /** The registered converters. */
     private Map<TypeLiteral<?>, List<PropertyConverter<?>>> converters = new ConcurrentHashMap<>();
+    /** The transitive converters as evaluated based on the registered converters. */
+    private Map<TypeLiteral<?>, List<PropertyConverter<?>>> transitiveConverters = new ConcurrentHashMap<>();
     /** The lock used. */
     private StampedLock lock = new StampedLock();
+
+    private static final Comparator<Object> PRIORITY_COMPARATOR =
+            (o1,o2) -> {
+                int prio = DefaultServiceContext.getPriority(o1) - DefaultServiceContext.getPriority(o2);
+                if(prio<0){
+                    return 1;
+                } else if(prio>0){
+                    return -1;
+                } else{
+                    return o1.getClass().getSimpleName().compareTo(o2.getClass().getSimpleName());
+                }
+            };
+
     /**
      * Constructor.
      */
@@ -91,7 +101,42 @@ public class PropertyConverterManager {
                 newConverters.addAll(converters);
             }
             newConverters.add(converter);
+            Collections.sort(newConverters, PRIORITY_COMPARATOR);
             this.converters.put(targetType, Collections.unmodifiableList(newConverters));
+            // evaluate transitive closure for all inherited supertypes and implemented interfaces
+            // direct implemented interfaces
+            for(Class<?> ifaceType: targetType.getRawType().getInterfaces()){
+                converters = List.class.cast(this.transitiveConverters.get(ifaceType));
+                newConverters = new ArrayList<>();
+                if (converters != null) {
+                    newConverters.addAll(converters);
+                }
+                newConverters.add(converter);
+                Collections.sort(newConverters, PRIORITY_COMPARATOR);
+                this.transitiveConverters.put(TypeLiteral.of(ifaceType), Collections.unmodifiableList(newConverters));
+            }
+            Class<?> superClass = targetType.getRawType().getSuperclass();
+            while(superClass!=null && !superClass.equals(Object.class)){
+                converters = List.class.cast(this.transitiveConverters.get(superClass));
+                newConverters = new ArrayList<>();
+                if (converters != null) {
+                    newConverters.addAll(converters);
+                }
+                newConverters.add(converter);
+                Collections.sort(newConverters, PRIORITY_COMPARATOR);
+                this.transitiveConverters.put(TypeLiteral.of(superClass), Collections.unmodifiableList(newConverters));
+                for(Class<?> ifaceType: superClass.getInterfaces()){
+                    converters = List.class.cast(this.transitiveConverters.get(ifaceType));
+                    newConverters = new ArrayList<>();
+                    if (converters != null) {
+                        newConverters.addAll(converters);
+                    }
+                    newConverters.add(converter);
+                    Collections.sort(newConverters, PRIORITY_COMPARATOR);
+                    this.transitiveConverters.put(TypeLiteral.of(ifaceType), Collections.unmodifiableList(newConverters));
+                }
+                superClass = superClass.getSuperclass();
+            }
         } finally {
             writeLock.unlock();
         }
@@ -104,14 +149,17 @@ public class PropertyConverterManager {
      * @return true, if a converter for the given type is registered, or a default one can be created.
      */
     public boolean isTargetTypeSupported(TypeLiteral<?> targetType) {
-        return converters.containsKey(targetType)
-                || createDefaultPropertyConverter(targetType) != null;
+        if(converters.containsKey(targetType) || transitiveConverters.containsKey(targetType)){
+            return true;
+        }
+        return createDefaultPropertyConverter(targetType) != null;
     }
 
     /**
      * Get a map of all property converters currently registered. This will not contain the converters that
      * may be created, when an instance is adapted, which provides a String constructor or compatible
-     * factory methods taking a single String instance.
+     * factory methods taking a single String instance. <br/>
+     * This will also NOT contain any transitive converter mappings as derived from the registered converters.
      *
      * @return the current map of instantiated and registered converters.
      * @see #createDefaultPropertyConverter(org.apache.tamaya.TypeLiteral)
@@ -129,7 +177,25 @@ public class PropertyConverterManager {
     /**
      * Get the list of all current registered converters for the given target type.
      * If not converters are registered, they component tries to create and register a dynamic
-     * converter based on String costructor or static factory methods available.
+     * converter based on String costructor or static factory methods available.<br/>
+     * The converters provided are of the following type and returned in the following order:
+     * <ul>
+     *     <li>Converters mapped explicitly to the required target type are returned first, ordered
+     *     by decreasing priority. This means, if explicit converters are registered these are used
+     *     primarly for converting a value.</li>
+     *     <li>The target type of each explicitly registered converter also can be transitively mapped to
+     *     1) all directly implemented interfaces, 2) all its superclasses (except Object), 3) all the interfaces
+     *     implemented by its superclasses. These groups of transitive converters is returned similarly in the
+     *     order as mentioned, whereas also here a priority based decreasing ordering is applied.</li>
+     *     <li>java.lang wrapper classes and native types are automatically mapped.</li>
+     *     <li>If no explicit converters are registered, for Enum types a default implementation is provided that
+     *     compares the configuration values with the different enum members defined (cases sensitive mapping).</li>
+     * </ul>
+     *
+     * So given that list above directly registered mappings always are tried first, before any transitive mapping
+     * should be used. Also in all cases @Priority annotations are honored for ordering of the converters in place.
+     * Transitive conversion is supported for all directly implemented interfaces (including inherited ones) and
+     * the inheritance hierarchy (exception Object). Superinterfaces of implemented interfaces are ignored.
      *
      * @param targetType the target type, not null.
      * @param <T>        the type class
@@ -137,8 +203,10 @@ public class PropertyConverterManager {
      * @see #createDefaultPropertyConverter(org.apache.tamaya.TypeLiteral)
      */
     public <T> List<PropertyConverter<T>> getPropertyConverters(TypeLiteral<T> targetType) {
+        List<PropertyConverter<T>> converterList = new ArrayList<>();
         Lock readLock = lock.asReadLock();
         List<PropertyConverter<T>> converters;
+        // direct mapped converters
         try {
             readLock.lock();
             converters = List.class.cast(this.converters.get(targetType));
@@ -146,8 +214,19 @@ public class PropertyConverterManager {
             readLock.unlock();
         }
         if (converters != null) {
-            return converters;
+            converterList.addAll(converters);
+        }
+        // transitive converter
+        try {
+            readLock.lock();
+            converters = List.class.cast(this.transitiveConverters.get(targetType));
+        } finally {
+            readLock.unlock();
+        }
+        if (converters != null) {
+            converterList.addAll(converters);
         }
+        // handling of java.lang wrapper classes
         TypeLiteral<T> boxedType = mapBoxedType(targetType);
         if(boxedType!=null){
             try {
@@ -157,23 +236,26 @@ public class PropertyConverterManager {
                 readLock.unlock();
             }
             if (converters != null) {
-                return converters;
+                converterList.addAll(converters);
             }
         }
-        PropertyConverter<T> defaultConverter = createDefaultPropertyConverter(targetType);
-        if (defaultConverter != null) {
-            register(targetType, defaultConverter);
-            try {
-                readLock.lock();
-                converters = List.class.cast(this.converters.get(targetType));
-            } finally {
-                readLock.unlock();
+        if(converterList.isEmpty()) {
+            // adding any converters created on the fly, e.g. for enum types.
+            PropertyConverter<T> defaultConverter = createDefaultPropertyConverter(targetType);
+            if (defaultConverter != null) {
+                register(targetType, defaultConverter);
+                try {
+                    readLock.lock();
+                    converters = List.class.cast(this.converters.get(targetType));
+                } finally {
+                    readLock.unlock();
+                }
+            }
+            if (converters != null) {
+                converterList.addAll(converters);
             }
         }
-        if (converters != null) {
-            return converters;
-        }
-        return Collections.emptyList();
+        return converterList;
     }
 
     /**
@@ -304,4 +386,5 @@ public class PropertyConverterManager {
         return null;
     }
 
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/4d560984/java8/core/src/test/java/org/apache/tamaya/core/internal/A.java
----------------------------------------------------------------------
diff --git a/java8/core/src/test/java/org/apache/tamaya/core/internal/A.java b/java8/core/src/test/java/org/apache/tamaya/core/internal/A.java
new file mode 100644
index 0000000..aa77a5d
--- /dev/null
+++ b/java8/core/src/test/java/org/apache/tamaya/core/internal/A.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.internal;
+
+/**
+ * Test class for testing transitively evaluated property converters.
+ */
+public class A implements AutoCloseable{
+    @Override
+    public void close() throws Exception {
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/4d560984/java8/core/src/test/java/org/apache/tamaya/core/internal/B.java
----------------------------------------------------------------------
diff --git a/java8/core/src/test/java/org/apache/tamaya/core/internal/B.java b/java8/core/src/test/java/org/apache/tamaya/core/internal/B.java
new file mode 100644
index 0000000..31bafb6
--- /dev/null
+++ b/java8/core/src/test/java/org/apache/tamaya/core/internal/B.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.internal;
+
+/**
+ * Test class for testing transitively evaluated property converters.
+ */
+public class B extends A implements Runnable{
+    @Override
+    public void run() {
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/4d560984/java8/core/src/test/java/org/apache/tamaya/core/internal/C.java
----------------------------------------------------------------------
diff --git a/java8/core/src/test/java/org/apache/tamaya/core/internal/C.java b/java8/core/src/test/java/org/apache/tamaya/core/internal/C.java
new file mode 100644
index 0000000..aad1ef9
--- /dev/null
+++ b/java8/core/src/test/java/org/apache/tamaya/core/internal/C.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.internal;
+
+import java.io.IOException;
+import java.nio.CharBuffer;
+
+/**
+ * Test class for testing transitively evaluated property converters.
+ */
+public class C extends B implements Readable{
+
+    private String inValue;
+
+    public C(String inValue){
+        this.inValue = inValue;
+    }
+
+    @Override
+    public int read(CharBuffer cb) throws IOException {
+        return 0;
+    }
+
+    /**
+     * Returns the input value, set on creation. Used for test assertion.
+     * @return the in value.
+     */
+    public String getInValue() {
+        return inValue;
+    }
+
+    @Override
+    public String toString() {
+        return "C{" +
+                "inValue='" + inValue + '\'' +
+                '}';
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/4d560984/java8/core/src/test/java/org/apache/tamaya/core/internal/CTestConverter.java
----------------------------------------------------------------------
diff --git a/java8/core/src/test/java/org/apache/tamaya/core/internal/CTestConverter.java b/java8/core/src/test/java/org/apache/tamaya/core/internal/CTestConverter.java
new file mode 100644
index 0000000..62b8c9d
--- /dev/null
+++ b/java8/core/src/test/java/org/apache/tamaya/core/internal/CTestConverter.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.internal;
+
+import org.apache.tamaya.spi.PropertyConverter;
+
+/**
+ * Created by Anatole on 13.06.2015.
+ */
+public class CTestConverter implements PropertyConverter<C>{
+    @Override
+    public C convert(String value) {
+        return new C(value);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/4d560984/java8/core/src/test/java/org/apache/tamaya/core/internal/PropertyConverterManagerTest.java
----------------------------------------------------------------------
diff --git a/java8/core/src/test/java/org/apache/tamaya/core/internal/PropertyConverterManagerTest.java b/java8/core/src/test/java/org/apache/tamaya/core/internal/PropertyConverterManagerTest.java
index fb80e05..9b413aa 100644
--- a/java8/core/src/test/java/org/apache/tamaya/core/internal/PropertyConverterManagerTest.java
+++ b/java8/core/src/test/java/org/apache/tamaya/core/internal/PropertyConverterManagerTest.java
@@ -74,4 +74,89 @@ public class PropertyConverterManagerTest {
         }
 
     }
+
+    @Test
+    public void testDirectConverterMapping(){
+        PropertyConverterManager manager = new PropertyConverterManager();
+        List<PropertyConverter<C>> converters = manager.getPropertyConverters(TypeLiteral.of(C.class));
+        assertThat(converters, hasSize(1));
+
+        PropertyConverter<C> converter = converters.get(0);
+        C result = converter.convert("testDirectConverterMapping");
+
+        assertThat(result, notNullValue());
+        assertThat(result, instanceOf(C.class));
+        assertThat(((C)result).getInValue(), equalTo("testDirectConverterMapping"));
+    }
+
+    @Test
+    public void testDirectSuperclassConverterMapping(){
+        PropertyConverterManager manager = new PropertyConverterManager();
+        List<PropertyConverter<B>> converters = manager.getPropertyConverters(TypeLiteral.of(B.class));
+        assertThat(converters, hasSize(1));
+
+        PropertyConverter<B> converter = converters.get(0);
+        B result = converter.convert("testDirectSuperclassConverterMapping");
+
+        assertThat(result, notNullValue());
+        assertThat(result, instanceOf(C.class));
+        assertThat(((C)result).getInValue(), equalTo("testDirectSuperclassConverterMapping"));
+    }
+
+    @Test
+    public void testTransitiveSuperclassConverterMapping(){
+        PropertyConverterManager manager = new PropertyConverterManager();
+        List<PropertyConverter<A>> converters = manager.getPropertyConverters(TypeLiteral.of(A.class));
+        assertThat(converters, hasSize(1));
+
+        PropertyConverter<A> converter = converters.get(0);
+        A result = converter.convert("testTransitiveSuperclassConverterMapping");
+
+        assertThat(result, notNullValue());
+        assertThat(result, instanceOf(C.class));
+        assertThat(((C)result).getInValue(), equalTo("testTransitiveSuperclassConverterMapping"));
+    }
+
+    @Test
+    public void testDirectInterfaceMapping(){
+        PropertyConverterManager manager = new PropertyConverterManager();
+        List<PropertyConverter<Readable>> converters = manager.getPropertyConverters(TypeLiteral.of(Readable.class));
+        assertThat(converters, hasSize(1));
+
+        PropertyConverter<Readable> converter = converters.get(0);
+        Readable result = converter.convert("testDirectInterfaceMapping");
+
+        assertThat(result, notNullValue());
+        assertThat(result, instanceOf(C.class));
+        assertThat(((C)result).getInValue(), equalTo("testDirectInterfaceMapping"));
+    }
+
+    @Test
+    public void testTransitiveInterfaceMapping1(){
+        PropertyConverterManager manager = new PropertyConverterManager();
+        List<PropertyConverter<Runnable>> converters = manager.getPropertyConverters(TypeLiteral.of(Runnable.class));
+        assertThat(converters, hasSize(1));
+
+        PropertyConverter<Runnable> converter = converters.get(0);
+        Runnable result = converter.convert("testTransitiveInterfaceMapping1");
+
+        assertThat(result, notNullValue());
+        assertThat(result, instanceOf(C.class));
+        assertThat(((C)result).getInValue(), equalTo("testTransitiveInterfaceMapping1"));
+    }
+
+    @Test
+    public void testTransitiveInterfaceMapping2(){
+        PropertyConverterManager manager = new PropertyConverterManager();
+        List<PropertyConverter<AutoCloseable>> converters = manager.getPropertyConverters(TypeLiteral.of(AutoCloseable.class));
+        assertThat(converters, hasSize(1));
+
+        PropertyConverter<AutoCloseable> converter = converters.get(0);
+        AutoCloseable result = converter.convert("testTransitiveInterfaceMapping2");
+
+        assertThat(result, notNullValue());
+        assertThat(result, instanceOf(C.class));
+        assertThat(((C)result).getInValue(), equalTo("testTransitiveInterfaceMapping2"));
+    }
+
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/4d560984/java8/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertyConverter
----------------------------------------------------------------------
diff --git a/java8/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertyConverter b/java8/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertyConverter
new file mode 100644
index 0000000..d039696
--- /dev/null
+++ b/java8/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertyConverter
@@ -0,0 +1,19 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy current the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+org.apache.tamaya.core.internal.CTestConverter
\ No newline at end of file