diff --git a/domino-jnx-api/src/main/java/com/hcl/domino/misc/JNXServiceFinder.java b/domino-jnx-api/src/main/java/com/hcl/domino/misc/JNXServiceFinder.java index 5e45cb08..f5c6d216 100644 --- a/domino-jnx-api/src/main/java/com/hcl/domino/misc/JNXServiceFinder.java +++ b/domino-jnx-api/src/main/java/com/hcl/domino/misc/JNXServiceFinder.java @@ -19,13 +19,14 @@ import java.security.AccessController; import java.security.PrivilegedAction; import java.util.Collection; +import java.util.Comparator; import java.util.Map; import java.util.NoSuchElementException; import java.util.ServiceLoader; +import java.util.Set; +import java.util.TreeSet; import java.util.concurrent.ConcurrentHashMap; -import java.util.stream.Collectors; import java.util.stream.Stream; -import java.util.stream.StreamSupport; /** * Utility class to coordinate service loading for JNX. @@ -81,9 +82,19 @@ public static T findRequiredService(final Class serviceClass, final Class @SuppressWarnings("unchecked") public static Stream findServices(final Class serviceClass) { return (Stream)SERVICE_CACHE.computeIfAbsent(serviceClass, c -> { - final Iterable services = AccessController + Set converters = new TreeSet<>(Comparator.comparing(o -> o.getClass().getName())); + + // Check the context (app) ClassLoader + Iterable services = AccessController .doPrivileged((PrivilegedAction>) () -> ServiceLoader.load(serviceClass)); - return StreamSupport.stream(services.spliterator(), false).collect(Collectors.toList()); + services.forEach(converters::add); + + // Also check the service's own ClassLoader, as it may be distinct + services = AccessController + .doPrivileged((PrivilegedAction>) () -> ServiceLoader.load(serviceClass, serviceClass.getClassLoader())); + services.forEach(converters::add); + + return converters; }).stream(); } } diff --git a/test/it-domino-jnx/src/test/java/it/com/hcl/domino/test/data/TestDocumentValueConversion.java b/test/it-domino-jnx/src/test/java/it/com/hcl/domino/test/data/TestDocumentValueConversion.java index e52cd276..2e36ddd7 100644 --- a/test/it-domino-jnx/src/test/java/it/com/hcl/domino/test/data/TestDocumentValueConversion.java +++ b/test/it-domino-jnx/src/test/java/it/com/hcl/domino/test/data/TestDocumentValueConversion.java @@ -17,6 +17,7 @@ package it.com.hcl.domino.test.data; import java.time.DateTimeException; +import java.time.Instant; import java.time.LocalDate; import java.time.LocalTime; import java.time.OffsetDateTime; @@ -377,4 +378,17 @@ public void testTimeRoundTrip() throws Exception { Assertions.assertEquals(LocalTime.from(expected), LocalTime.from(date)); }); } + + @Test + public void testInstantRoundTrip() throws Exception { + final Instant expected = Instant.ofEpochSecond(System.currentTimeMillis() / 1000); + + withTempDb(database -> { + final Document doc = database.createDocument(); + + doc.replaceItemValue("Foo", expected); + final Instant date = doc.get("Foo", Instant.class, null); + Assertions.assertEquals(Instant.from(expected), Instant.from(date)); + }); + } }