WebAppClassLoader may fail if concurrent threads try to load a not-yet-loaded class. Scenario: two threads enter loadClass(name, resolve) (line 1214) concurrently. none of them finds a loaded class, so both enter findClass (827) and findClassInternal (1559). Now one thread goes ahead, finds the resource and defines the class. Consequently, it sets entry.binaryContent to null (1633). Thread 2 now checks binaryContent for null (1572) and throws a ClassNotFoundException. In the field, this error occurs, if you start Tomcat and load a number of different jsps concurrently that all use the same tag class. I also have a standalone testcase where I made WCL#addRepository(String,File) public. As it seems, #loadClass(String, boolean) (1211) should be synchronized, as in the superclasses. Matthias
Created attachment 14362 [details] standalone testcase Test produces output like the following: class hox.util.Util intermingled with java.lang.ClassNotFoundException: hox.util.Util at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1332) at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1181) at org.apache.catalina.loader.test.WCT$1.run(WCT.java:35)
This will not be fixed for now.
Great. It leads to compiled JSP classes that do *not* recover by reloading. They have a persistent "NoClassDefFoundError" attached. Will you apply the fix in 5.5 ?
No, I will not apply your proposed fix. As it is, I cannot reproduce any problem using the provided tester (so if I cannot do it using a microtest, it is even less likely to occur in HTTP land). Maybe thread startup time is too slow on my test machine. I see that there's a flaw in the current syncing, however, and I am willing to apply the attached patch which should resolve the problem.
Created attachment 14585 [details] Syncing when checking binaryContent==null
My patch should address the possible race on entry.binaryContent.
On which version is this fixed? (kind of urgent for me to know...thanks!)
Hi, the bug was reported on 5.0.28, I've seen it on 5.0.27 and 5.0.30. A patch was made, but doesn't say which build is fixed.
Fixed in 5.5.10 onwards.