ij.jar
is still a single JAR after all these years. It brings a lot of downsides, but also advantages.
-SNAPSHOT
, which of course doesn't always guarantees it fetches what you are thinking). However, gradle request goes in overtime and then the synchronization gets interrupted as unresolved and you have to trigger it again.${lastTag}+$numberOfCommits
and then you can immediately consume somewhere else
-jdk8
variant (Maven should have something similar but I dont know the term for that) for retro-compatibility
src/it/discovery-test
, should I put the tests in there?
So I currently have regression tests for:
OpInfo
s discoverable using ServiceLoader
OpInfo
s discoverable using ServiceLoader
OpInfo
s discoverable using Therapi (this number is currently zero)Do we want a matching regression test? If so, what Ops should be tested? There are some math Ops which make sense to test, but what about adapt
Ops? simplify
Ops?
public static Iterable<Discoverer> all(Function<Class<Discoverer>, ? extends ServiceLoader<Discoverer>> func) {
return (ServiceLoader<Discoverer>) func.apply(Discoverer.class);
}
static <T> Iterable<Discoverer> all(Function<Class<T>, ? extends ServiceLoader<T>> func) {
try {
ServiceLoader<Discoverer> d = (ServiceLoader<Discoverer>) func.apply((Class<T>) Discoverer.class);
List<Discoverer> list = d.stream().map(p -> p.get()).collect(Collectors.toList());
list.add(Discoverer.using(func));
return list;
} catch (ClassCastException e) {
return Collections.emptyList();
} catch (ServiceConfigurationError e) {
return Collections.emptyList();
}
}
I do think it would be fun to write a
Discoverer
backed by classgraph, though.
Right, yeah. I just meant that it would not fix the problem we were talking about yesterday
public class ClassGraphDiscoverer implements Discoverer {
@Override
public <T> List<T> discover(Class<T> type) {
List<T> instances = new ArrayList<>();
try (ScanResult scanResult = new ClassGraph().enableAllInfo().scan()) {
ClassInfoList impls = scanResult.getSubclasses(type);
for (ClassInfo impl : impls) {
try {
Class<?> c = impl.loadClass();
if (!type.isAssignableFrom(c))) continue; // Not an implementation of the requested type.
T instance = (T) c.newInstance();
instances.add(instance);
}
catch (IllegalArgumentException exc) {
// NB: Could not load the class.
// TODO: Log the exception.
}
catch (ExceptionTypesThatNewInstanceThrows exc) {
// NB: Could not instantiate the class.
// TODO: Log the exception.
}
}
}
return instances;
}
}
discover
may rescan the classpath (‽).
getSubclasses
may return abstract layers, not only "leaf class" implementations. So probably more checking is needed here before trying to instantiate each class. Maybe also checking for a no-args constructor? I dunno.