Skip to content

Commit 9fb7218

Browse files
authored
Merge pull request #338 from avaje/feature/alternate-serviceLoading
Use alternative to ServiceLoader to load Plugin and PropertyRequiresPlugin
2 parents 80ccac5 + 0c067ed commit 9fb7218

File tree

1 file changed

+32
-2
lines changed

1 file changed

+32
-2
lines changed

inject/src/main/java/io/avaje/inject/DBeanScopeBuilder.java

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,14 @@
77
import io.avaje.lang.Nullable;
88
import jakarta.inject.Provider;
99

10+
import java.io.*;
1011
import java.lang.reflect.Type;
12+
import java.net.URL;
1113
import java.util.*;
1214
import java.util.function.Consumer;
1315
import java.util.function.Supplier;
16+
import java.util.stream.Collectors;
17+
import java.util.stream.Stream;
1418

1519
import static java.lang.System.Logger.Level.DEBUG;
1620

@@ -187,7 +191,7 @@ private void initClassLoader() {
187191

188192
private void initPropertyPlugin() {
189193
propertyRequiresPlugin =
190-
ServiceLoader.load(PropertyRequiresPlugin.class, classLoader)
194+
serviceLoad(PropertyRequiresPlugin.class)
191195
.findFirst()
192196
.orElse(defaultPropertyPlugin());
193197
}
@@ -214,7 +218,7 @@ public BeanScope build() {
214218
initPropertyPlugin();
215219
}
216220

217-
ServiceLoader.load(Plugin.class, classLoader).forEach(plugin -> plugin.apply(this));
221+
serviceLoad(Plugin.class).forEach(plugin -> plugin.apply(this));
218222
// sort factories by dependsOn
219223
FactoryOrder factoryOrder = new FactoryOrder(parent, includeModules, !suppliedBeans.isEmpty());
220224
if (factoryOrder.isEmpty()) {
@@ -241,6 +245,32 @@ public BeanScope build() {
241245
return builder.build(shutdownHook, start);
242246
}
243247

248+
private <P> Stream<P> serviceLoad(Class<P> pluginClass) {
249+
return classLoader
250+
.resources("META-INF/services/" + pluginClass.getCanonicalName())
251+
.flatMap(this::resourceLines)
252+
.map(this::serviceInstance);
253+
}
254+
255+
@SuppressWarnings("unchecked")
256+
private <P> P serviceInstance(String className) {
257+
try {
258+
final var clazz = classLoader.loadClass(className);
259+
return (P) clazz.getDeclaredConstructor().newInstance();
260+
} catch (Throwable e) {
261+
throw new RuntimeException(e);
262+
}
263+
}
264+
265+
private Stream<String> resourceLines(URL url) {
266+
try (InputStream is = url.openStream()) {
267+
final var reader = new LineNumberReader(new InputStreamReader(is));
268+
return reader.lines().collect(Collectors.toList()).stream();
269+
} catch (IOException e) {
270+
throw new UncheckedIOException(e);
271+
}
272+
}
273+
244274
/**
245275
* Return the type that we map the supplied bean to.
246276
*/

0 commit comments

Comments
 (0)