mirror of
https://github.com/yacy/yacy_search_server.git
synced 2026-10-25 05:54:15 +00:00
Fixed concurrency issue in custom classloader used for template classes
As reported in issue #241, the problem is only critical (random but complete crash of the JVM) when upgrading to JDK11.
This commit is contained in:
1 parent
0eb52f8c72
commit
7a62fc0e66
1 file changed
+24
-16
@@ -70,7 +70,7 @@ public final class serverClassLoader extends ClassLoader {
|
||||
|
||||
/**
|
||||
* A special loadClass using file as argument to find and load a class
|
||||
* This methode is directly called by the application and not part of the
|
||||
* This method is directly called by the application and not part of the
|
||||
* normal loadClass chain (= never called by JVM)
|
||||
*
|
||||
* @param classfile
|
||||
@@ -84,22 +84,30 @@ public final class serverClassLoader extends ClassLoader {
|
||||
if (p < 0) throw new ClassNotFoundException("wrong class name: " + classfile.getName());
|
||||
final String classname = classfile.getName().substring(0, p);
|
||||
|
||||
// load the file from the file system
|
||||
byte[] b;
|
||||
try {
|
||||
//System.out.println("*** DEBUG CLASSLOADER: " + classfile + "; file " + (classfile.exists() ? "exists": "does not exist"));
|
||||
b = FileUtils.read(classfile);
|
||||
// make a class out of the stream
|
||||
c = this.defineClass(null, b, 0, b.length);
|
||||
resolveClass(c);
|
||||
} catch (final LinkageError ee) {
|
||||
synchronized (this) {
|
||||
/* Important : we must first synchronize any concurrent access AND then check if the class was not already loaded.
|
||||
* Otherwise, trying to define again the same class (with the defineClass function) may lead to a JVM crash on some platforms,
|
||||
* notably when running on Java 11 (on earlier JVMs, a LinkageError was only triggered and gracefully catched in that case) */
|
||||
c = findLoadedClass(classname);
|
||||
if (c != null) return c;
|
||||
throw new ClassNotFoundException("linkageError, " + ee.getMessage() + ":" + classfile.toString());
|
||||
} catch (final IOException ee) {
|
||||
throw new ClassNotFoundException(ee.getMessage() + ":" + classfile.toString());
|
||||
}
|
||||
return c;
|
||||
if (c != null) {
|
||||
return c;
|
||||
}
|
||||
|
||||
// load the file from the file system
|
||||
byte[] b;
|
||||
try {
|
||||
b = FileUtils.read(classfile);
|
||||
// make a class out of the stream
|
||||
c = this.defineClass(null, b, 0, b.length);
|
||||
resolveClass(c);
|
||||
} catch (final LinkageError ee) {
|
||||
/* This error could occur when two threads try to define concurrently the same class. Should not occur here */
|
||||
throw new ClassNotFoundException("linkageError, " + ee.getMessage() + ":" + classfile.toString());
|
||||
} catch (final IOException ee) {
|
||||
throw new ClassNotFoundException(ee.getMessage() + ":" + classfile.toString());
|
||||
}
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user