Creating snapshots with dynamically loaded JARs
Nikola Grcevski
grcevski at gmail.com
Fri Dec 2 19:30:02 UTC 2022
Hello crac-dev,
While experimenting more with CRaC and Elasticsearch I encountered one
more issue and I thought I should bring it up for discussion.
We load some JARs dynamically and these don't get marked as 'persistent'.
For example:
final ClassLoader classLoader = buildClassLoader();
try {
final Class<? extends Supplier<?>> cls = (Class<? extends
Supplier<?>>)classLoader.loadClass("org.elasticsearch.io.ansi.AnsiConsoleLoader");
...
} catch (ReflectiveOperationException e) {
throw new RuntimeException("Failed to load ANSI console", e);
}
private static ClassLoader buildClassLoader() {
final Path libDir = Path.of(".").resolve("lib").resolve("ansi-console");
try {
final URL[] urls = Files.list(libDir)
.filter(each ->
each.getFileName().toString().endsWith(".jar"))
.map(SimpleModule::pathToURL)
.toArray(URL[]::new);
return URLClassLoader.newInstance(urls,
SimpleModule.class.getClassLoader());
} catch (IOException e) {
throw new RuntimeException("Failed to list jars in [" + libDir
+ "]: " + e.getMessage(), e);
}
}
I think typically we'd say that these should be closed and recreated
on snapshot and restore,
but it's not easy to do with ClassLoaders. I think we'd need to lose
the reference and have
GC collect the class loader for all the files to close.
I was able to work around this issue by putting all the jars we might
load dynamically
on the class path with -cp.
I'm wondering if the work around is the correct 'fix' or is there something
else that should be done? If the URLs are files, I suppose we can mark those as
persistent?
I made a GitHub repo with all the code that shows the issue here:
https://github.com/grcevski/openjdk_CRaC_simplemodule
Thanks,
Nikola
More information about the crac-dev
mailing list