tamaya-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From anat...@apache.org
Subject [incubator-tamaya] 03/04: TAMAYA-398 TAMAYA-399 TAMAYA-400 TAMAYA-401 TAMAYA-402 TAMAYA-403 TAMAYA-404 TAMAYA-405 TAMAYA-406 TAMAYA-407 Implemented MP 1.3 spec.
Date Tue, 14 May 2019 14:52:07 GMT
This is an automated email from the ASF dual-hosted git repository.

anatole pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-tamaya.git

commit b3089cde2b635ce2ec0e4cc73f1578c47efac573
Author: Anatole Tresch <atsticks@gmail.com>
AuthorDate: Tue May 14 14:41:37 2019 +0200

    TAMAYA-398 TAMAYA-399 TAMAYA-400 TAMAYA-401 TAMAYA-402 TAMAYA-403 TAMAYA-404 TAMAYA-405 TAMAYA-406 TAMAYA-407 Implemented MP 1.3 spec.
---
 .../main/java/org/apache/tamaya/Configuration.java |  2 +-
 .../apache/tamaya/spi/ConfigurationBuilder.java    | 10 ++++
 .../org/apache/tamaya/spi/ConversionContext.java   | 14 ++++++
 .../java/org/apache/tamaya/spi/PropertyValue.java  | 16 ------
 .../java/org/apache/tamaya/spi/ServiceContext.java | 44 ++++++++++++++---
 .../apache/tamaya/spi/ServiceContextManager.java   |  9 +++-
 .../tamaya/spi/ConfigurationBuilderTest.java       |  5 ++
 .../org/apache/tamaya/spi/PropertyValueTest.java   | 17 -------
 .../tamaya/spi/ServiceContextManagerTest.java      |  5 +-
 .../tamaya/spi/TestLowerOrdinalServiceContext.java |  2 +-
 .../org/apache/tamaya/spi/TestServiceContext.java  | 14 +++++-
 code/core/pom.xml                                  |  2 +-
 .../core/internal/CoreConfigurationProvider.java   |  2 +-
 .../core/internal/OSGIServiceComparator.java       |  9 ++--
 .../tamaya/core/internal/OSGIServiceContext.java   |  4 +-
 .../converters/LocalDateTimeConverter.java         |  2 +
 ...teTimeConverter.java => MonthDayConverter.java} | 16 +++---
 ...alDateTimeConverter.java => YearConverter.java} | 16 +++---
 ...eTimeConverter.java => YearMonthConverter.java} | 17 ++++---
 .../org.apache.tamaya.spi.PropertyConverter        |  3 ++
 .../core/internal/OSGIServiceContextTest.java      |  7 +--
 .../tamaya/spisupport/DefaultConfiguration.java    | 29 +++++++++--
 .../spisupport/DefaultConfigurationBuilder.java    | 21 ++++++--
 .../spisupport/DefaultConfigurationContext.java    | 57 ++++++++++++++++++----
 .../spisupport/DefaultConfigurationSnapshot.java   |  8 ++-
 .../tamaya/spisupport/DefaultServiceContext.java   |  1 -
 .../spisupport/PriorityServiceComparator.java      | 10 ++--
 .../spisupport/PropertyConverterManager.java       | 40 ++++++++++-----
 .../spisupport/PropertyFilterComparator.java       | 17 +++++--
 .../spisupport/PropertySourceComparator.java       |  3 +-
 .../propertysource/EnvironmentPropertySource.java  | 15 ++++--
 .../JavaConfigurationPropertySource.java           | 17 ++-----
 .../PropertiesResourcePropertySource.java          | 10 +++-
 .../spisupport/services/DefaultServiceContext.java | 25 +++++++---
 34 files changed, 325 insertions(+), 144 deletions(-)

diff --git a/code/api/src/main/java/org/apache/tamaya/Configuration.java b/code/api/src/main/java/org/apache/tamaya/Configuration.java
index 7c47211..083f494 100644
--- a/code/api/src/main/java/org/apache/tamaya/Configuration.java
+++ b/code/api/src/main/java/org/apache/tamaya/Configuration.java
@@ -461,7 +461,7 @@ public interface Configuration {
      * @return the builder, never null.
      */
     static ConfigurationBuilder createConfigurationBuilder(){
-        return ServiceContextManager.getServiceContext(Configuration.class.getClassLoader())
+        return ServiceContextManager.getServiceContext(ServiceContextManager.getDefaultClassLoader())
                 .getService(ConfigurationProviderSpi.class).getConfigurationBuilder();
     }
 
diff --git a/code/api/src/main/java/org/apache/tamaya/spi/ConfigurationBuilder.java b/code/api/src/main/java/org/apache/tamaya/spi/ConfigurationBuilder.java
index d8f1393..ccc6244 100644
--- a/code/api/src/main/java/org/apache/tamaya/spi/ConfigurationBuilder.java
+++ b/code/api/src/main/java/org/apache/tamaya/spi/ConfigurationBuilder.java
@@ -378,6 +378,16 @@ public interface ConfigurationBuilder {
     ConfigurationBuilder sortPropertyFilter(Comparator<PropertyFilter> comparator);
 
     /**
+     * Sorts the current registered property converters using the given comparator.
+     *
+     * <p>NOTE: property converters at the beginning have minimal significance.
+     *
+     * @param comparator the comparator to be used, not {@code null}.
+     * @return this instance for chaining.
+     */
+    ConfigurationBuilder sortPropertyConverter(Comparator<PropertyConverter> comparator);
+
+    /**
      * Builds a new {@link Configuration} based on the data in this builder. The ordering of property
      * sources and property filters is not changed, regardless of their ordinals. For ensure a certain
      * ordering/significance use {@link #sortPropertyFilter(Comparator)} and/or {@link #sortPropertySources(Comparator)}
diff --git a/code/api/src/main/java/org/apache/tamaya/spi/ConversionContext.java b/code/api/src/main/java/org/apache/tamaya/spi/ConversionContext.java
index a52b884..c7156fb 100644
--- a/code/api/src/main/java/org/apache/tamaya/spi/ConversionContext.java
+++ b/code/api/src/main/java/org/apache/tamaya/spi/ConversionContext.java
@@ -141,6 +141,20 @@ public class ConversionContext {
         }
     }
 
+    /**
+     * Creates a builder based on this instance.
+     */
+    public Builder toBuilder(){
+        Builder builder = new Builder(key, targetType)
+                .setConfiguration(this.configuration)
+                .setValues(this.values);
+        if(annotatedElement!=null) {
+            builder.setAnnotatedElement(annotatedElement);
+        }
+        builder.supportedFormats.addAll(this.supportedFormats);
+        return builder;
+    }
+
     @Override
     public String toString() {
         return "ConversionContext{" +
diff --git a/code/api/src/main/java/org/apache/tamaya/spi/PropertyValue.java b/code/api/src/main/java/org/apache/tamaya/spi/PropertyValue.java
index 712f1d6..3e9da06 100644
--- a/code/api/src/main/java/org/apache/tamaya/spi/PropertyValue.java
+++ b/code/api/src/main/java/org/apache/tamaya/spi/PropertyValue.java
@@ -63,22 +63,6 @@ public class PropertyValue implements Serializable, Iterable<PropertyValue>{
     }
 
 
-//    /**
-//     * Creates a new builder instance.
-//     * @param key the key, not {@code null}.
-//     * @param source the source, typically the name of the {@link PropertySource}
-//     *               providing the createValue, not {@code null}.
-//     * @return a new builder instance.
-//     * @deprecated Will be removed, use {@link PropertyValue} directly.
-//     */
-//    @Deprecated
-//    public static PropertyValueBuilder builder(String key, String source){
-//        Objects.requireNonNull(key, "Key must be given.");
-//        Objects.requireNonNull(source, "Source must be given");
-//
-//        return new PropertyValueBuilder(key, null).setSource(source);
-//    }
-
     /**
      * Creates a new (invisible) root, which is a node with an empty name.
      * @return a new empty root, never null.
diff --git a/code/api/src/main/java/org/apache/tamaya/spi/ServiceContext.java b/code/api/src/main/java/org/apache/tamaya/spi/ServiceContext.java
index 3d97e93..ae82c07 100644
--- a/code/api/src/main/java/org/apache/tamaya/spi/ServiceContext.java
+++ b/code/api/src/main/java/org/apache/tamaya/spi/ServiceContext.java
@@ -23,6 +23,8 @@ import java.io.IOException;
 import java.net.URL;
 import java.util.*;
 import java.util.function.Supplier;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 
 /**
@@ -32,6 +34,24 @@ import java.util.function.Supplier;
 public interface ServiceContext extends ClassloaderAware{
 
     /**
+     * True if the {@link Priority} annotation class is available on the classpath.
+     */
+    boolean PRIORITY_ANNOTATION_AVAILABLE = checkPriorityAnnotation(ServiceContextManager.getDefaultClassLoader());
+
+    /**
+     * Checks if the {@link Priority} annotation class is on the classpath.
+     * @param classLoader the target classloader, not null.
+     * @return true, if the annotation is loaded.
+     */
+    static boolean checkPriorityAnnotation(ClassLoader classLoader) {
+        try{
+            Class.forName("javax.annotation.Priority", true, classLoader);
+            return true;
+        }catch(Exception e){
+            return false;
+        }
+    }
+    /**
      * Get the ordinal of the ServiceContext.
      * @return ordinal of the ServiceContext. The one with the highest ordinal will be taken.
      */
@@ -46,10 +66,12 @@ public interface ServiceContext extends ClassloaderAware{
      * @return a priority, by default 1.
      */
     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();
+        int prio = 1;
+        if(PRIORITY_ANNOTATION_AVAILABLE) {
+            Priority priority = o.getClass().getAnnotation(Priority.class);
+            if (priority != null) {
+                prio = priority.value();
+            }
         }
         return prio;
     }
@@ -149,8 +171,18 @@ public interface ServiceContext extends ClassloaderAware{
      * @return the resources found
      * @throws IOException if load fails.
      */
-    default Enumeration<URL> getResources(String resource) throws IOException{
-        return getClassLoader().getResources(resource);
+    default Collection<URL> getResources(String resource){
+        List<URL> urls = new ArrayList<>();
+        try {
+            Enumeration<URL> found = getClassLoader().getResources(resource);
+            while (found.hasMoreElements()) {
+                urls.add(found.nextElement());
+            }
+        }catch(Exception e){
+            Logger.getLogger(ServiceContext.class.getName())
+                    .log(Level.FINEST, e, () -> "Failed to lookup resources: " + resource);
+        }
+        return urls;
     }
 
     /**
diff --git a/code/api/src/main/java/org/apache/tamaya/spi/ServiceContextManager.java b/code/api/src/main/java/org/apache/tamaya/spi/ServiceContextManager.java
index 2acbfca..7d81fe1 100644
--- a/code/api/src/main/java/org/apache/tamaya/spi/ServiceContextManager.java
+++ b/code/api/src/main/java/org/apache/tamaya/spi/ServiceContextManager.java
@@ -140,10 +140,15 @@ public final class ServiceContextManager {
     }
 
     /**
-     * Evaluate the default classloader: This class's classloader.
+     * Evaluate the default classloader: This return the current thread context classloader, or this
+     * class's classloader as fallback.
      * @return the classloder, not null.
      */
     public static ClassLoader getDefaultClassLoader() {
-        return ServiceContextManager.class.getClassLoader();
+        ClassLoader cl = Thread.currentThread().getContextClassLoader();
+        if(cl==null) {
+            cl = ServiceContextManager.class.getClassLoader();
+        }
+        return cl;
     }
 }
diff --git a/code/api/src/test/java/org/apache/tamaya/spi/ConfigurationBuilderTest.java b/code/api/src/test/java/org/apache/tamaya/spi/ConfigurationBuilderTest.java
index cdd3414..3fde90e 100644
--- a/code/api/src/test/java/org/apache/tamaya/spi/ConfigurationBuilderTest.java
+++ b/code/api/src/test/java/org/apache/tamaya/spi/ConfigurationBuilderTest.java
@@ -231,6 +231,11 @@ public class ConfigurationBuilderTest {
         }
 
         @Override
+        public ConfigurationBuilder sortPropertyConverter(Comparator<PropertyConverter> comparator) {
+            return null;
+        }
+
+        @Override
         public Configuration build() {
             return null;
         }
diff --git a/code/api/src/test/java/org/apache/tamaya/spi/PropertyValueTest.java b/code/api/src/test/java/org/apache/tamaya/spi/PropertyValueTest.java
index b3f03ff..694ef50 100644
--- a/code/api/src/test/java/org/apache/tamaya/spi/PropertyValueTest.java
+++ b/code/api/src/test/java/org/apache/tamaya/spi/PropertyValueTest.java
@@ -30,23 +30,6 @@ import static org.assertj.core.api.Assertions.assertThatCode;
 @SuppressWarnings("unchecked")
 public class PropertyValueTest {
 
-//    @Test
-//    public void builder() throws Exception {
-//        PropertyValueBuilder b = PropertyValue.builder("a", "b");
-//        assertThat(b).isNotNull();
-//        assertThat("a").isEqualTo(b.key);
-//        assertThat("b").isEqualTo(b.source);
-//    }
-//
-//
-//    @Test
-//    public void builder() throws Exception {
-//        PropertyValueBuilder b = PropertyValue.builder("a", "b");
-//        assertThat(b).isNotNull();
-//        assertThat("a").isEqualTo(b.key);
-//        assertThat("b").isEqualTo(b.source);
-//    }
-
     @Test
     public void from(){
 
diff --git a/code/api/src/test/java/org/apache/tamaya/spi/ServiceContextManagerTest.java b/code/api/src/test/java/org/apache/tamaya/spi/ServiceContextManagerTest.java
index a72ea2b..761a429 100644
--- a/code/api/src/test/java/org/apache/tamaya/spi/ServiceContextManagerTest.java
+++ b/code/api/src/test/java/org/apache/tamaya/spi/ServiceContextManagerTest.java
@@ -22,6 +22,7 @@ import org.junit.Test;
 
 import java.io.IOException;
 import java.net.URL;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Enumeration;
 import java.util.List;
@@ -88,8 +89,8 @@ public class ServiceContextManagerTest {
         }
 
         @Override
-        public Enumeration<URL> getResources(String resource) throws IOException {
-            return null;
+        public Collection<URL> getResources(String resource) {
+            return Collections.emptySet();
         }
 
         @Override
diff --git a/code/api/src/test/java/org/apache/tamaya/spi/TestLowerOrdinalServiceContext.java b/code/api/src/test/java/org/apache/tamaya/spi/TestLowerOrdinalServiceContext.java
index 6c5beb4..39bc87a 100644
--- a/code/api/src/test/java/org/apache/tamaya/spi/TestLowerOrdinalServiceContext.java
+++ b/code/api/src/test/java/org/apache/tamaya/spi/TestLowerOrdinalServiceContext.java
@@ -77,7 +77,7 @@ public final class TestLowerOrdinalServiceContext implements ServiceContext {
     }
 
     @Override
-    public Enumeration<URL> getResources(String resource) throws IOException {
+    public Collection<URL> getResources(String resource) {
         throw ex;
     }
 
diff --git a/code/api/src/test/java/org/apache/tamaya/spi/TestServiceContext.java b/code/api/src/test/java/org/apache/tamaya/spi/TestServiceContext.java
index b00a7a0..765c032 100644
--- a/code/api/src/test/java/org/apache/tamaya/spi/TestServiceContext.java
+++ b/code/api/src/test/java/org/apache/tamaya/spi/TestServiceContext.java
@@ -113,8 +113,18 @@ public final class TestServiceContext implements ServiceContext {
     }
 
     @Override
-    public Enumeration<URL> getResources(String resource) throws IOException {
-        return classLoader.getResources(resource);
+    public Collection<URL> getResources(String resource) {
+        List<URL> urls = new ArrayList<>();
+        try {
+            Enumeration<URL> found = getClassLoader().getResources(resource);
+            while (found.hasMoreElements()) {
+                urls.add(found.nextElement());
+            }
+        }catch(Exception e){
+            Logger.getLogger(ServiceContext.class.getName())
+                    .log(Level.FINEST, e, () -> "Failed to lookup resources: " + resource);
+        }
+        return urls;
     }
 
     @Override
diff --git a/code/core/pom.xml b/code/core/pom.xml
index 51397cf..8220e62 100644
--- a/code/core/pom.xml
+++ b/code/core/pom.xml
@@ -98,7 +98,7 @@ under the License.
                     <!--
                      ! Add -Djava.security.debug=all for debugging if needed
                      !-->
-                    <argLine>-Djava.security.policy=${project.basedir}/src/test/resources/java-security.policy ${argLine}</argLine>
+                    <argLine>-Djava.security.policy=${project.basedir}/src/test/resources/java-security.policy</argLine>
                 </configuration>
             </plugin>
         </plugins>
diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/CoreConfigurationProvider.java b/code/core/src/main/java/org/apache/tamaya/core/internal/CoreConfigurationProvider.java
index bbfecf6..989821b 100644
--- a/code/core/src/main/java/org/apache/tamaya/core/internal/CoreConfigurationProvider.java
+++ b/code/core/src/main/java/org/apache/tamaya/core/internal/CoreConfigurationProvider.java
@@ -82,7 +82,7 @@ public class CoreConfigurationProvider implements ConfigurationProviderSpi {
         Objects.requireNonNull(config.getContext());
         Configuration old = this.configurations.put(classLoader, Objects.requireNonNull(config));
         if(old != null){
-            LOG.warning(String.format("Replaced config %S with %S for classloader %S", old, config, classLoader));
+            LOG.warning(String.format("Replaced config %s with %s for classloader %s", old, config, classLoader));
         }
     }
 
diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/OSGIServiceComparator.java b/code/core/src/main/java/org/apache/tamaya/core/internal/OSGIServiceComparator.java
index f039d27..6cd16e9 100644
--- a/code/core/src/main/java/org/apache/tamaya/core/internal/OSGIServiceComparator.java
+++ b/code/core/src/main/java/org/apache/tamaya/core/internal/OSGIServiceComparator.java
@@ -18,6 +18,7 @@
  */
 package org.apache.tamaya.core.internal;
 
+import org.apache.tamaya.spi.ServiceContext;
 import org.osgi.framework.ServiceReference;
 
 import javax.annotation.Priority;
@@ -61,9 +62,11 @@ class OSGIServiceComparator implements Comparator<ServiceReference> {
      */
     public static int getPriority(Class<? extends Object> type) {
         int prio = 1;
-        Priority priority = type.getAnnotation(Priority.class);
-        if (priority != null) {
-            prio = priority.value();
+        if(ServiceContext.PRIORITY_ANNOTATION_AVAILABLE) {
+            Priority priority = type.getAnnotation(Priority.class);
+            if (priority != null) {
+                prio = priority.value();
+            }
         }
         return prio;
     }
diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/OSGIServiceContext.java b/code/core/src/main/java/org/apache/tamaya/core/internal/OSGIServiceContext.java
index 2d67dc8..9eeac72 100644
--- a/code/core/src/main/java/org/apache/tamaya/core/internal/OSGIServiceContext.java
+++ b/code/core/src/main/java/org/apache/tamaya/core/internal/OSGIServiceContext.java
@@ -167,7 +167,7 @@ public class OSGIServiceContext implements ServiceContext{
     }
 
     @Override
-    public Enumeration<URL> getResources(String resource) throws IOException{
+    public Collection<URL> getResources(String resource){
         LOG.finest("TAMAYA  Loading resources: " + resource);
         List<URL> result = new ArrayList<>();
         URL url = osgiServiceLoader.getBundleContext().getBundle()
@@ -191,7 +191,7 @@ public class OSGIServiceContext implements ServiceContext{
                 result.add(url);
             }
         }
-        return Collections.enumeration(result);
+        return result;
     }
 
     @Override
diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/converters/LocalDateTimeConverter.java b/code/core/src/main/java/org/apache/tamaya/core/internal/converters/LocalDateTimeConverter.java
index 92f2d75..b7fedee 100644
--- a/code/core/src/main/java/org/apache/tamaya/core/internal/converters/LocalDateTimeConverter.java
+++ b/code/core/src/main/java/org/apache/tamaya/core/internal/converters/LocalDateTimeConverter.java
@@ -23,6 +23,7 @@ import org.apache.tamaya.spi.PropertyConverter;
 import org.osgi.service.component.annotations.Component;
 
 import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
 import java.util.Objects;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -35,6 +36,7 @@ public class LocalDateTimeConverter implements PropertyConverter<LocalDateTime>
 
     private static final Logger LOG = Logger.getLogger(LocalDateTimeConverter.class.getName());
 
+
     @Override
     public LocalDateTime convert(String value, ConversionContext ctx) {
         ctx.addSupportedFormats(getClass(), LocalDateTime.now().toString());
diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/converters/LocalDateTimeConverter.java b/code/core/src/main/java/org/apache/tamaya/core/internal/converters/MonthDayConverter.java
similarity index 73%
copy from code/core/src/main/java/org/apache/tamaya/core/internal/converters/LocalDateTimeConverter.java
copy to code/core/src/main/java/org/apache/tamaya/core/internal/converters/MonthDayConverter.java
index 92f2d75..f6331b7 100644
--- a/code/core/src/main/java/org/apache/tamaya/core/internal/converters/LocalDateTimeConverter.java
+++ b/code/core/src/main/java/org/apache/tamaya/core/internal/converters/MonthDayConverter.java
@@ -22,29 +22,29 @@ import org.apache.tamaya.spi.ConversionContext;
 import org.apache.tamaya.spi.PropertyConverter;
 import org.osgi.service.component.annotations.Component;
 
-import java.time.LocalDateTime;
+import java.time.MonthDay;
 import java.util.Objects;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
 /**
- * Converter, converting from String to LocalDateTime.
+ * Converter, converting from String to Year.
  */
 @Component(service = PropertyConverter.class)
-public class LocalDateTimeConverter implements PropertyConverter<LocalDateTime> {
+public class MonthDayConverter implements PropertyConverter<MonthDay> {
 
-    private static final Logger LOG = Logger.getLogger(LocalDateTimeConverter.class.getName());
+    private static final Logger LOG = Logger.getLogger(MonthDayConverter.class.getName());
 
     @Override
-    public LocalDateTime convert(String value, ConversionContext ctx) {
-        ctx.addSupportedFormats(getClass(), LocalDateTime.now().toString());
+    public MonthDay convert(String value, ConversionContext ctx) {
+        ctx.addSupportedFormats(getClass(), MonthDay.now().toString());
         if(value==null){
             return null;
         }
         try{
-            return LocalDateTime.parse(value);
+            return MonthDay.parse(value);
         }catch(Exception e){
-            LOG.log(Level.FINEST, e, () -> "Cannot parse LocalDateTime: " + value);
+            LOG.log(Level.FINEST, e, () -> "Cannot parse MonthDay: " + value);
             return null;
         }
     }
diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/converters/LocalDateTimeConverter.java b/code/core/src/main/java/org/apache/tamaya/core/internal/converters/YearConverter.java
similarity index 73%
copy from code/core/src/main/java/org/apache/tamaya/core/internal/converters/LocalDateTimeConverter.java
copy to code/core/src/main/java/org/apache/tamaya/core/internal/converters/YearConverter.java
index 92f2d75..414d891 100644
--- a/code/core/src/main/java/org/apache/tamaya/core/internal/converters/LocalDateTimeConverter.java
+++ b/code/core/src/main/java/org/apache/tamaya/core/internal/converters/YearConverter.java
@@ -22,29 +22,29 @@ import org.apache.tamaya.spi.ConversionContext;
 import org.apache.tamaya.spi.PropertyConverter;
 import org.osgi.service.component.annotations.Component;
 
-import java.time.LocalDateTime;
+import java.time.Year;
 import java.util.Objects;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
 /**
- * Converter, converting from String to LocalDateTime.
+ * Converter, converting from String to Year.
  */
 @Component(service = PropertyConverter.class)
-public class LocalDateTimeConverter implements PropertyConverter<LocalDateTime> {
+public class YearConverter implements PropertyConverter<Year> {
 
-    private static final Logger LOG = Logger.getLogger(LocalDateTimeConverter.class.getName());
+    private static final Logger LOG = Logger.getLogger(YearConverter.class.getName());
 
     @Override
-    public LocalDateTime convert(String value, ConversionContext ctx) {
-        ctx.addSupportedFormats(getClass(), LocalDateTime.now().toString());
+    public Year convert(String value, ConversionContext ctx) {
+        ctx.addSupportedFormats(getClass(), Year.now().toString());
         if(value==null){
             return null;
         }
         try{
-            return LocalDateTime.parse(value);
+            return Year.parse(value);
         }catch(Exception e){
-            LOG.log(Level.FINEST, e, () -> "Cannot parse LocalDateTime: " + value);
+            LOG.log(Level.FINEST, e, () -> "Cannot parse Year: " + value);
             return null;
         }
     }
diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/converters/LocalDateTimeConverter.java b/code/core/src/main/java/org/apache/tamaya/core/internal/converters/YearMonthConverter.java
similarity index 73%
copy from code/core/src/main/java/org/apache/tamaya/core/internal/converters/LocalDateTimeConverter.java
copy to code/core/src/main/java/org/apache/tamaya/core/internal/converters/YearMonthConverter.java
index 92f2d75..a66bffe 100644
--- a/code/core/src/main/java/org/apache/tamaya/core/internal/converters/LocalDateTimeConverter.java
+++ b/code/core/src/main/java/org/apache/tamaya/core/internal/converters/YearMonthConverter.java
@@ -22,29 +22,30 @@ import org.apache.tamaya.spi.ConversionContext;
 import org.apache.tamaya.spi.PropertyConverter;
 import org.osgi.service.component.annotations.Component;
 
-import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.YearMonth;
 import java.util.Objects;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
 /**
- * Converter, converting from String to LocalDateTime.
+ * Converter, converting from String to YearMonth.
  */
 @Component(service = PropertyConverter.class)
-public class LocalDateTimeConverter implements PropertyConverter<LocalDateTime> {
+public class YearMonthConverter implements PropertyConverter<YearMonth> {
 
-    private static final Logger LOG = Logger.getLogger(LocalDateTimeConverter.class.getName());
+    private static final Logger LOG = Logger.getLogger(YearMonthConverter.class.getName());
 
     @Override
-    public LocalDateTime convert(String value, ConversionContext ctx) {
-        ctx.addSupportedFormats(getClass(), LocalDateTime.now().toString());
+    public YearMonth convert(String value, ConversionContext ctx) {
+        ctx.addSupportedFormats(getClass(), YearMonth.now().toString());
         if(value==null){
             return null;
         }
         try{
-            return LocalDateTime.parse(value);
+            return YearMonth.parse(value);
         }catch(Exception e){
-            LOG.log(Level.FINEST, e, () -> "Cannot parse LocalDateTime: " + value);
+            LOG.log(Level.FINEST, e, () -> "Cannot parse YearMonth: " + value);
             return null;
         }
     }
diff --git a/code/core/src/main/resources/META-INF/services/org.apache.tamaya.spi.PropertyConverter b/code/core/src/main/resources/META-INF/services/org.apache.tamaya.spi.PropertyConverter
index 396aef1..1320a98 100644
--- a/code/core/src/main/resources/META-INF/services/org.apache.tamaya.spi.PropertyConverter
+++ b/code/core/src/main/resources/META-INF/services/org.apache.tamaya.spi.PropertyConverter
@@ -28,6 +28,7 @@ org.apache.tamaya.core.internal.converters.ShortConverter
 org.apache.tamaya.core.internal.converters.BigDecimalConverter
 org.apache.tamaya.core.internal.converters.BigIntegerConverter
 org.apache.tamaya.core.internal.converters.CurrencyConverter
+org.apache.tamaya.core.internal.converters.MonthDayConverter
 org.apache.tamaya.core.internal.converters.NumberConverter
 org.apache.tamaya.core.internal.converters.URIConverter
 org.apache.tamaya.core.internal.converters.URLConverter
@@ -42,3 +43,5 @@ org.apache.tamaya.core.internal.converters.OffsetTimeConverter
 org.apache.tamaya.core.internal.converters.InstantConverter
 org.apache.tamaya.core.internal.converters.OptionalConverter
 org.apache.tamaya.core.internal.converters.SupplierConverter
+org.apache.tamaya.core.internal.converters.YearConverter
+org.apache.tamaya.core.internal.converters.YearMonthConverter
diff --git a/code/core/src/test/java/org/apache/tamaya/core/internal/OSGIServiceContextTest.java b/code/core/src/test/java/org/apache/tamaya/core/internal/OSGIServiceContextTest.java
index e3227cc..9c69039 100644
--- a/code/core/src/test/java/org/apache/tamaya/core/internal/OSGIServiceContextTest.java
+++ b/code/core/src/test/java/org/apache/tamaya/core/internal/OSGIServiceContextTest.java
@@ -20,6 +20,7 @@ package org.apache.tamaya.core.internal;
 
 import java.io.IOException;
 import java.net.URL;
+import java.util.Collection;
 import java.util.Enumeration;
 import java.util.List;
 
@@ -98,11 +99,11 @@ public class OSGIServiceContextTest {
         mockBundleContext.installBundle(startedBundle);
         OSGIServiceContext instance = new OSGIServiceContext(loader);
 
-        Enumeration<URL> resources = instance.getResources("dummy");
+        Collection<URL> resources = instance.getResources("dummy");
         assertThat(resources).isNotNull();
-        URL resource = (URL)resources.nextElement();
+        URL resource = (URL)resources.iterator().next();
         assertThat(resource.toString()).contains("mockbundle.service");
-        assertThat(resources.hasMoreElements()).isFalse();
+        assertThat(resources.size()).isEqualTo(1);
     }
 
     /**
diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfiguration.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfiguration.java
index a5cf45b..a41c068 100644
--- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfiguration.java
+++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfiguration.java
@@ -29,6 +29,10 @@ import org.apache.tamaya.spi.ConversionContext;
 import org.apache.tamaya.spi.PropertyConverter;
 import org.apache.tamaya.spi.PropertyValue;
 
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
 import java.util.*;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -38,7 +42,7 @@ import java.util.logging.Logger;
  * chain of {@link org.apache.tamaya.spi.PropertySource} and {@link org.apache.tamaya.spi.PropertyFilter}
  * instances to evaluate the current Configuration.
  */
-public class DefaultConfiguration implements Configuration {
+public class DefaultConfiguration implements Configuration, Serializable {
     /**
      * The logger.
      */
@@ -47,12 +51,12 @@ public class DefaultConfiguration implements Configuration {
     /**
      * The current {@link ConfigurationContext} of the current instance.
      */
-    private final ConfigurationContext configurationContext;
+    private ConfigurationContext configurationContext;
 
     /**
      * EvaluationStrategy
      */
-    private ConfigValueEvaluator configEvaluator;
+    private transient ConfigValueEvaluator configEvaluator;
 
 
     private ConfigValueEvaluator loadConfigValueEvaluator() {
@@ -301,4 +305,23 @@ public class DefaultConfiguration implements Configuration {
                 configurationContext +
                 '}';
     }
+
+    private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
+        configurationContext = (ConfigurationContext)ois.readObject();
+        configEvaluator = loadConfigValueEvaluator();
+    }
+
+    private void writeObject(ObjectOutputStream oos) throws IOException {
+        if(configurationContext instanceof Serializable){
+            oos.writeObject(configurationContext);
+        }else{
+            oos.writeObject(new DefaultConfigurationContext(
+                    this.configurationContext.getServiceContext(),
+                    this.configurationContext.getPropertyFilters(),
+                    this.configurationContext.getPropertySources(),
+                    this.configurationContext.getPropertyConverters(),
+                    this.configurationContext.getServiceContext().getService(MetadataProvider.class,
+                            () -> new DefaultMetaDataProvider())));
+        }
+    }
 }
diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationBuilder.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationBuilder.java
index 0123148..d050638 100644
--- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationBuilder.java
+++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationBuilder.java
@@ -61,6 +61,7 @@ public class DefaultConfigurationBuilder implements ConfigurationBuilder {
      * Creates a new builder instance.
      */
     public DefaultConfigurationBuilder() {
+
     }
 
 
@@ -87,6 +88,7 @@ public class DefaultConfigurationBuilder implements ConfigurationBuilder {
     @Override
     public ConfigurationBuilder setClassLoader(ClassLoader classLoader) {
         setServiceContext(ServiceContextManager.getServiceContext(classLoader));
+        serviceContext.reset();
         return this;
     }
 
@@ -149,9 +151,14 @@ public class DefaultConfigurationBuilder implements ConfigurationBuilder {
     public ConfigurationBuilder addPropertySources(Collection<PropertySource> sources){
         checkBuilderState();
         for(PropertySource source:sources) {
-            if (!this.propertySources.contains(source)) {
-                this.propertySources.add(source);
+            if(this.propertySources.stream()
+                    .filter(ex -> Objects.equals(ex.getName(), source.getName()))
+                    .findAny()
+                    .isPresent()){
+                LOG.finest(() -> "Omitting already present property source: " + source.getName());
+                continue;
             }
+            this.propertySources.add(source);
         }
         return this;
     }
@@ -308,7 +315,7 @@ public class DefaultConfigurationBuilder implements ConfigurationBuilder {
             if (!converters.contains(propertyConverter)) {
                 converters.add(propertyConverter);
             } else {
-                LOG.warning("Converter ignored, already registered: " + propertyConverter);
+                LOG.finest("Converter ignored, already registered: " + propertyConverter);
             }
         }
         return this;
@@ -346,6 +353,14 @@ public class DefaultConfigurationBuilder implements ConfigurationBuilder {
     }
 
     @Override
+    public ConfigurationBuilder sortPropertyConverter(Comparator<PropertyConverter> comparator) {
+        for(List<PropertyConverter<?>> converters:this.propertyConverters.values()) {
+            Collections.sort(converters, comparator);
+        }
+        return this;
+    }
+
+    @Override
     public List<PropertyFilter> getPropertyFilters() {
         return this.propertyFilters;
     }
diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationContext.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationContext.java
index e01adb5..7d65fa5 100644
--- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationContext.java
+++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationContext.java
@@ -19,25 +19,26 @@
 package org.apache.tamaya.spisupport;
 
 import org.apache.tamaya.TypeLiteral;
-import org.apache.tamaya.spi.ConfigurationContext;
-import org.apache.tamaya.spi.PropertyConverter;
-import org.apache.tamaya.spi.PropertyFilter;
-import org.apache.tamaya.spi.PropertySource;
-import org.apache.tamaya.spi.PropertyValue;
-import org.apache.tamaya.spi.ServiceContext;
+import org.apache.tamaya.spi.*;
 
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
 import java.util.*;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 import java.util.logging.Logger;
+import java.util.stream.Collectors;
 
 /**
  * Default implementation of a simple {@link ConfigurationContext}.
  */
-public class DefaultConfigurationContext implements ConfigurationContext {
+public class DefaultConfigurationContext implements ConfigurationContext, Serializable {
 
     /** The logger used. */
     private final static Logger LOG = Logger.getLogger(DefaultConfigurationContext.class.getName());
-    private final MetadataProvider metaDataProvider;
+
+    private MetadataProvider metaDataProvider;
 
     /**
      * Subcomponent handling {@link PropertyConverter} instances.
@@ -61,7 +62,7 @@ public class DefaultConfigurationContext implements ConfigurationContext {
     /**
      * Lock for internal synchronization.
      */
-    private final ReentrantReadWriteLock propertySourceLock = new ReentrantReadWriteLock();
+    private ReentrantReadWriteLock propertySourceLock = new ReentrantReadWriteLock();
 
     @SuppressWarnings("unchecked")
     protected DefaultConfigurationContext(DefaultConfigurationBuilder builder) {
@@ -268,4 +269,42 @@ public class DefaultConfigurationContext implements ConfigurationContext {
         return immutablePropertyFilters;
     }
 
+    /**
+     * Evaluates all present keys from the property sources loaded.
+     * @return the keys found, never null.
+     */
+    private Set<String> getKeys() {
+        Set<String> keys = new HashSet<>();
+        for(PropertySource ps:immutablePropertySources){
+            keys.addAll(ps.getProperties().keySet());
+        }
+        return keys;
+    }
+
+    /**
+     * Deserialization only reads the property source snapshots from the stream. Converters, filters,
+     * meta data provider and the service context are reinitialized based on the current environment.
+     * @param ois the input stream
+     * @throws IOException if the stream is corrupted
+     * @throws ClassNotFoundException if s property source class cannot be serialized.
+     */
+    private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
+        this.serviceContext = ServiceContextManager.getServiceContext();
+        this.propertyConverterManager = new PropertyConverterManager(
+                this.serviceContext, true);
+        this.immutablePropertySources = Collections.unmodifiableList(
+                (List<PropertySource>)ois.readObject());
+        this.immutablePropertyFilters = Collections.unmodifiableList(
+                this.serviceContext.getServices(PropertyFilter.class));
+        this.metaDataProvider = this.serviceContext.getService(MetadataProvider.class);
+        propertySourceLock = new ReentrantReadWriteLock();
+    }
+
+    private void writeObject(ObjectOutputStream oos)throws IOException{
+        // omit converters, they will be reloaded from scratch.
+        oos.writeObject(this.immutablePropertySources.stream()
+                .map(ps -> DefaultPropertySourceSnapshot.of(ps, getKeys())).collect(Collectors.toList()));
+        // omit filters, they will be reloaded from scratch
+    }
+
 }
diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationSnapshot.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationSnapshot.java
index ac4fe8b..15ee71c 100644
--- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationSnapshot.java
+++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationSnapshot.java
@@ -24,6 +24,8 @@ import org.apache.tamaya.TypeLiteral;
 import org.apache.tamaya.spi.ConfigurationContext;
 import org.apache.tamaya.spi.PropertyConverter;
 
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
 import java.io.Serializable;
 import java.util.*;
 import java.util.stream.Collectors;
@@ -40,10 +42,10 @@ public class DefaultConfigurationSnapshot implements ConfigurationSnapshot, Seri
     /**
      * The properties frozen.
      */
-    private Configuration snapshot;
+    private DefaultConfiguration snapshot;
     private long frozenAt = System.nanoTime();
     private UUID id = UUID.randomUUID();
-    private transient ConfigurationContext context;
+    private DefaultConfigurationContext context;
     private Set<String> keys = new HashSet<>();
 
     /**
@@ -101,6 +103,7 @@ public class DefaultConfigurationSnapshot implements ConfigurationSnapshot, Seri
      * Get the evaluated keys of this frozen coinfiguration.
      * @return the keys, not null.
      */
+    @Override
     public Set<String> getKeys() {
         return keys;
     }
@@ -209,4 +212,5 @@ public class DefaultConfigurationSnapshot implements ConfigurationSnapshot, Seri
     public UUID getId() {
         return id;
     }
+
 }
diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultServiceContext.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultServiceContext.java
index 9b63a99..9bd1040 100644
--- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultServiceContext.java
+++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultServiceContext.java
@@ -22,7 +22,6 @@ import org.apache.tamaya.ConfigException;
 import org.apache.tamaya.spi.ClassloaderAware;
 import org.apache.tamaya.spi.ServiceContext;
 
-import javax.annotation.Priority;
 import java.text.MessageFormat;
 import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PriorityServiceComparator.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PriorityServiceComparator.java
index ef68eed..25bdbc3 100644
--- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PriorityServiceComparator.java
+++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PriorityServiceComparator.java
@@ -18,6 +18,8 @@
  */
 package org.apache.tamaya.spisupport;
 
+import org.apache.tamaya.spi.ServiceContext;
+
 import javax.annotation.Priority;
 import java.io.Serializable;
 import java.util.Comparator;
@@ -75,9 +77,11 @@ public class PriorityServiceComparator implements Comparator<Object>, Serializab
     @SuppressWarnings({ "rawtypes", "unchecked" })
     public static int getPriority(Class type) {
         int prio = 1;
-        Priority priority = (Priority)type.getAnnotation(Priority.class);
-        if (priority != null) {
-            prio = priority.value();
+        if(ServiceContext.PRIORITY_ANNOTATION_AVAILABLE) {
+            Priority priority = (Priority) type.getAnnotation(Priority.class);
+            if (priority != null) {
+                prio = priority.value();
+            }
         }
         return prio;
     }
diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyConverterManager.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyConverterManager.java
index 5782526..0654712 100644
--- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyConverterManager.java
+++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyConverterManager.java
@@ -28,6 +28,7 @@ import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.lang.reflect.Type;
+import java.net.URI;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.*;
@@ -254,6 +255,15 @@ public class PropertyConverterManager {
                 readLock.unlock();
             }
         }
+        if(converterList.isEmpty() && targetType.getRawType().isArray() &&
+            !targetType.getRawType().getComponentType().isPrimitive()){
+            try {
+                readLock.lock();
+                addConvertersToList(List.class.cast(this.converters.get(TypeLiteral.of(Object[].class))), converterList);
+            } finally {
+                readLock.unlock();
+            }
+        }
         if (converterList.isEmpty() && !TypeLiteral.of(String.class).equals(targetType)) {
             // adding any converters created on the fly, e.g. for enum types.
             PropertyConverter<T> defaultConverter = createDefaultPropertyConverter(targetType);
@@ -364,36 +374,38 @@ public class PropertyConverterManager {
             return new EnumConverter<>(targetType.getRawType());
         }
         PropertyConverter<T> converter = null;
-        final Method factoryMethod = getFactoryMethod(targetType.getRawType(), "of", "createValue", "instanceOf", "getInstance", "from", "fromString", "parse");
+        final Method factoryMethod = getFactoryMethod(targetType.getRawType(), "of", "valueOf", "createValue", "instanceOf", "getInstance", "from", "fromString", "parse");
         if (factoryMethod != null) {
             converter = new DefaultPropertyConverter<>(factoryMethod, targetType.getRawType());
         }
         if (converter == null) {
-            final Constructor<T> constr;
+            Constructor<T> constr;
             try {
                 constr = targetType.getRawType().getDeclaredConstructor(String.class);
             } catch (NoSuchMethodException e) {
-                LOG.log(Level.FINEST, "No matching constructor for " + targetType, e);
-                return null;
+                try {
+                    constr = targetType.getRawType().getDeclaredConstructor(CharSequence.class);
+                } catch (NoSuchMethodException e2) {
+                    LOG.log(Level.FINEST, "No matching constructor found for " + targetType);
+                    return null;
+                }
             }
+            Constructor<T> finalConstr = constr;
             converter = new PropertyConverter<T>() {
                     @Override
                     public T convert(String value, ConversionContext context) {
                         AccessController.doPrivileged(new PrivilegedAction<Object>() {
                             @Override
                             public Object run() {
-                                AccessController.doPrivileged(new PrivilegedAction<Object>() {
-                                    @Override
-                                    public Object run() {
-                                        constr.setAccessible(true);
-                                        return null;
-                                    }
+                                AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
+                                    finalConstr.setAccessible(true);
+                                    return null;
                                 });
                                 return null;
                             }
                         });
                         try {
-                            return constr.newInstance(value);
+                            return finalConstr.newInstance(value);
                         } catch (Exception e) {
                             LOG.log(Level.SEVERE, "Error creating new PropertyConverter instance " + targetType, e);
                         }
@@ -418,6 +430,12 @@ public class PropertyConverterManager {
                 m = type.getDeclaredMethod(name, String.class);
                 return m;
             } catch (NoSuchMethodException | RuntimeException e) {
+                // continue, try also with CharSequence
+            }
+            try {
+                m = type.getDeclaredMethod(name, CharSequence.class);
+                return m;
+            } catch (NoSuchMethodException | RuntimeException e) {
                 LOG.finest("No such factory method found on type: " + type.getName() + ", methodName: " + name);
             }
         }
diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyFilterComparator.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyFilterComparator.java
index c1d5520..3d0d501 100644
--- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyFilterComparator.java
+++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyFilterComparator.java
@@ -19,6 +19,7 @@
 package org.apache.tamaya.spisupport;
 
 import org.apache.tamaya.spi.PropertyFilter;
+import org.apache.tamaya.spi.ServiceContext;
 
 import javax.annotation.Priority;
 import java.io.Serializable;
@@ -51,11 +52,19 @@ public final class PropertyFilterComparator implements Comparator<PropertyFilter
      * @return the comparison result
      */
     private int comparePropertyFilters(PropertyFilter filter1, PropertyFilter filter2) {
-        Priority prio1 = filter1.getClass().getAnnotation(Priority.class);
-        Priority prio2 = filter2.getClass().getAnnotation(Priority.class);
-        int ord1 = prio1 != null ? prio1.value() : 0;
-        int ord2 = prio2 != null ? prio2.value() : 0;
+        int ord1 = 0;
+        int ord2 = 0;
 
+        if(ServiceContext.PRIORITY_ANNOTATION_AVAILABLE) {
+            Priority prio1 = filter1.getClass().getAnnotation(Priority.class);
+            Priority prio2 = filter2.getClass().getAnnotation(Priority.class);
+            if(prio1!=null) {
+                ord1 = prio1.value();
+            }
+            if(prio2!=null) {
+                ord2 = prio2.value();
+            }
+        }
         if (ord1 < ord2) {
             return -1;
         } else if (ord1 > ord2) {
diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertySourceComparator.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertySourceComparator.java
index 3222635..3a35c37 100644
--- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertySourceComparator.java
+++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertySourceComparator.java
@@ -21,7 +21,6 @@ package org.apache.tamaya.spisupport;
 import org.apache.tamaya.spi.PropertySource;
 import org.apache.tamaya.spi.PropertyValue;
 
-import javax.annotation.Priority;
 import java.io.Serializable;
 import java.util.Comparator;
 import java.util.logging.Logger;
@@ -76,7 +75,7 @@ public class PropertySourceComparator implements Comparator<PropertySource>, Ser
      *     to convert it to an {@code int} createValue, using {@link Integer#parseInt(String)}.</li>
      *     <li>It tries to find and evaluate a method {@code int getOrdinal()}.</li>
      *     <li>It tries to find and evaluate a static field {@code int ORDINAL}.</li>
-     *     <li>It tries to find and evaluate a class level {@link Priority} annotation.</li>
+     *     <li>It tries to find and evaluate a class level {@link javax.annotation.Priority} annotation.</li>
      *     <li>It uses the default priority ({@code 0}.</li>
      * </ol>
      * @param propertySource the property source, not {@code null}.
diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/EnvironmentPropertySource.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/EnvironmentPropertySource.java
index c53bd76..ae156f5 100644
--- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/EnvironmentPropertySource.java
+++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/EnvironmentPropertySource.java
@@ -198,6 +198,13 @@ public class EnvironmentPropertySource extends BasePropertySource {
         return "environment-properties";
     }
 
+    /*
+    Exact match (i.e. com.ACME.size)
+
+Replace the character that is neither alphanumeric nor _ with _ (i.e. com_ACME_size)
+
+Replace the character that is neither alphanumeric nor _ with _ and convert to upper case (i.e. COM_ACME_SIZE)
+     */
     @Override
     public PropertyValue get(String key) {
         if (isDisabled()) {
@@ -209,12 +216,13 @@ public class EnvironmentPropertySource extends BasePropertySource {
         String value = getPropertiesProvider().getenv(effectiveKey);
         // Replace all . by _ (i.e. com_ACME_size)
         if(value==null){
-            value = getPropertiesProvider().getenv(effectiveKey.replaceAll("\\.", "_"));
+            effectiveKey = effectiveKey.replaceAll("\\W", "_");
+            value = getPropertiesProvider().getenv(effectiveKey);
         }
         // Replace all . by _ and convert to upper case (i.e. COM_ACME_SIZE)
         if(value==null){
-            value = getPropertiesProvider().getenv(effectiveKey.replaceAll("\\.", "_")
-                    .toUpperCase());
+            effectiveKey = effectiveKey.toUpperCase();
+            value = getPropertiesProvider().getenv(effectiveKey);
         }
         if(value==null){
             return null;
@@ -222,6 +230,7 @@ public class EnvironmentPropertySource extends BasePropertySource {
         return PropertyValue.createValue(key, value).setMeta("source", getName());
     }
 
+
     private boolean hasPrefix() {
         return null != prefix && prefix.isEmpty();
     }
diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/JavaConfigurationPropertySource.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/JavaConfigurationPropertySource.java
index 598808d..990a025 100644
--- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/JavaConfigurationPropertySource.java
+++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/JavaConfigurationPropertySource.java
@@ -86,23 +86,12 @@ public class JavaConfigurationPropertySource extends BasePropertySource implemen
 
     private Collection<? extends PropertySource> loadPropertySourcesByName(String filename, ClassLoader classLoader) {
         List<PropertySource> propertySources = new ArrayList<>();
-        Enumeration<URL> propertyLocations;
-        try {
-            propertyLocations = ServiceContextManager.getServiceContext(classLoader)
+        Collection<URL> propertyLocations = ServiceContextManager.getServiceContext(classLoader)
                     .getResources(filename);
-        } catch (IOException e) {
-            String msg = format("Error while searching for %s", filename);
 
-            throw new ConfigException(msg, e);
+        for (URL currentUrl:propertyLocations) {
+            propertySources.add(new SimplePropertySource(currentUrl));
         }
-
-        while (propertyLocations.hasMoreElements()) {
-            URL currentUrl = propertyLocations.nextElement();
-            SimplePropertySource sps = new SimplePropertySource(currentUrl);
-
-            propertySources.add(sps);
-        }
-
         return propertySources;
     }
 
diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/PropertiesResourcePropertySource.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/PropertiesResourcePropertySource.java
index 13dfd7d..9cd264a 100644
--- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/PropertiesResourcePropertySource.java
+++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/PropertiesResourcePropertySource.java
@@ -18,12 +18,14 @@
  */
 package org.apache.tamaya.spisupport.propertysource;
 
+import org.apache.tamaya.ConfigException;
 import org.apache.tamaya.spi.ChangeSupport;
 import org.apache.tamaya.spi.PropertySource;
 import org.apache.tamaya.spi.PropertyValue;
 import org.apache.tamaya.spi.ServiceContextManager;
 import org.apache.tamaya.spisupport.PropertySourceChangeSupport;
 
+import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
 import java.util.*;
@@ -88,8 +90,12 @@ public class PropertiesResourcePropertySource extends BasePropertySource {
      * @return the loaded properties.
      */
     private Map<String, PropertyValue> loadProps(String path, ClassLoader cl) {
-        URL url = ServiceContextManager.getServiceContext(cl).getResource(path);
-        return loadProps(url);
+        try {
+            URL url = ServiceContextManager.getServiceContext(cl).getResource(path);
+            return loadProps(url);
+        }catch(Exception e){
+            throw new ConfigException("Failed to load properties from " + path, e);
+        }
     }
 
     /**
diff --git a/code/spi-support/src/test/java/org/apache/tamaya/spisupport/services/DefaultServiceContext.java b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/services/DefaultServiceContext.java
index 257baab..7bd0506 100644
--- a/code/spi-support/src/test/java/org/apache/tamaya/spisupport/services/DefaultServiceContext.java
+++ b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/services/DefaultServiceContext.java
@@ -22,6 +22,7 @@ import org.apache.tamaya.ConfigException;
 import org.apache.tamaya.spi.ClassloaderAware;
 import org.apache.tamaya.spi.ServiceContext;
 import org.apache.tamaya.spisupport.PriorityServiceComparator;
+import org.apache.tamaya.spisupport.propertysource.SimplePropertySource;
 
 import javax.annotation.Priority;
 import java.io.IOException;
@@ -150,10 +151,12 @@ public final class DefaultServiceContext implements ServiceContext {
      * @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();
+        int prio = 1;
+        if(ServiceContext.PRIORITY_ANNOTATION_AVAILABLE) {
+            Priority priority = o.getClass().getAnnotation(Priority.class);
+            if (priority != null) {
+                prio = priority.value();
+            }
         }
         return prio;
     }
@@ -213,8 +216,18 @@ public final class DefaultServiceContext implements ServiceContext {
     }
 
     @Override
-    public Enumeration<URL> getResources(String resource) throws IOException {
-        return classLoader.getResources(resource);
+    public Collection<URL> getResources(String resource) {
+        List<URL> urls = new ArrayList<>();
+        try {
+            Enumeration<URL> found = getClassLoader().getResources(resource);
+            while (found.hasMoreElements()) {
+                urls.add(found.nextElement());
+            }
+        }catch(Exception e){
+            Logger.getLogger(ServiceContext.class.getName())
+                    .log(Level.FINEST, e, () -> "Failed to lookup resources: " + resource);
+        }
+        return urls;
     }
 
     @Override


Mime
View raw message