-
Notifications
You must be signed in to change notification settings - Fork 150
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Loading Native Libraries as Stream in Multithreaded Environment #103
Comments
Hi, thanks for pointing this out. Did this fix the problem? If yes, can you open a pull request with these changes? |
Yes - we fixed this by applying this change in a snapshot version.
I'm still totally not sure about the underlying issue - i.e. I'd like to
write an SSCCE using core Java, and then potentially raise a bug report...
but I haven't had time yet!
(I will say that if it is a bug in core Java, it completely ruined my
weekend when we upgraded from Java 7 to Java 8!)
TBH - I had issues doing a clone from github (corporate firewalls etc.), so
i ended up downloading a source .zip, and working from there.
So... until I can get that worked out with the powers that be, I don't
think I'll be able to submit any changes. Sorry.
Also, I'm not sure what you might want to do with the Exception handling -
i.e. what your thoughts/approach are for handling checked exceptions.
Kind regards,
Anthony
…On 13 April 2018 at 20:38, Mikio L. Braun ***@***.***> wrote:
Hi,
thanks for pointing this out. Did this fix the problem? If yes, can you
open a pull request with these changes?
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#103 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AQLBEbreBX8W0OxUZ_M_l9hEZjRtkqicks5toP7NgaJpZM4TMNA6>
.
|
Hey Anthony, corporate firewalls so you cannot even clone from github!? Sounds awful! ;) Alright, thanks for taking the time, I'll add the patch. Pretty little time to work on this right now, but I promise it'll eventually make it in! Best, Mikio |
The exception happens when you try sharing one My library FastClasspathScanner uses one ZipFile instance per thread, and I never run into this issue, so it's not a JDK bug. It's a bug in how libraries are using the |
Hi lukehutch, thanks for clarifying! |
Uh, by the way, just thinking. Wouldn't it be best to lock the part that loads the code because that is something that should be done only once anyway? |
@mikiobraun you're welcome :-) It took me a while to figure out how to parallelize access to a zipfile too, and this bug seems relatively common. You're right that a class can be loaded only once, and the classloading system will make sure that a class is loaded into a given classloader at most once, through the class caching system, which has its own lock, and works fine in a multithreaded environment. My comment above applies only to In summary, if you want multiple threads to read from the same zipfile in a scalable way, you must open one Protip: if you really care about speed, you can get more performance by reading all the |
When initializing JBLAS in a heavily multi-threaded environment in Java 8, I'm finding that I get the following exception:
Caused by: java.lang.NullPointerException: Inflater has been closed
at java.util.zip.Inflater.ensureOpen(Inflater.java:389)
at java.util.zip.Inflater.inflate(Inflater.java:257)
at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:152)
at java.io.FilterInputStream.read(FilterInputStream.java:133)
at java.io.FilterInputStream.read(FilterInputStream.java:107)
at org.jblas.util.LibraryLoader.loadLibraryFromStream(LibraryLoader.java:261)
at org.jblas.util.LibraryLoader.loadLibrary(LibraryLoader.java:186)
at org.jblas.NativeBlasLibraryLoader.loadLibraryAndCheckErrors(NativeBlasLibraryLoader.java:32)
at org.jblas.NativeBlas.(NativeBlas.java:77)
My best guess at the moment it that that there's a concurrency bug in core Java 8, such that resources loaded as a stream can be closed by the same JarFile/ZipFile being closed elsewhere. For similar examples, see this issue in org.reflections.reflections (ronmamo/reflections#81), or this issue on StackOverflow (https://stackoverflow.com/questions/49697901/java-xml-resource-inputstream-being-closed/49717516#49717516)
I would suggest that, in LibraryLoader.tryPath(String path), you change from:
private InputStream tryPath(String path) {
Logger.getLogger().debug("Trying path "" + path + "".");
return this.getClass().getResourceAsStream(path);
}
to:
private InputStream tryPath(String path) {
Logger.getLogger().debug("Trying path "" + path + "".");
try {
URLConnection connection = this.getClass.getResource(path).openConnection();
connection.setUseCaches(false);
return connection.getInputStream();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
The text was updated successfully, but these errors were encountered: