Hi, Recently I had catalina log grow in few seconds to enormous sizes, partially due to problems with mentioned method. Instead of creating and declared ClassNotFoundException it throws "java.lang.IllegalStateException: Can't overwrite cause". Looking into the code I found here: http://grepcode.com/file/repo1.maven.org/maven2/org.apache.tomcat/tomcat-catalina/8.0.23/org/apache/catalina/loader/WebappClassLoaderBase.java#WebappClassLoaderBase.checkStateForClassLoading%28java.lang.String%29 1309 protected void checkStateForClassLoading(String className) throws ClassNotFoundException { 1310 // It is not permitted to load new classes once the web application has 1311 // been stopped. 1312 try { 1313 checkStateForResourceLoading(className); 1314 } catch (IllegalStateException ise) { 1315 ClassNotFoundException cnfe = new ClassNotFoundException(); 1316 cnfe.initCause(ise); 1317 throw cnfe; 1318 } 1319 } I belive the problem is caused by setting initcause on created class when constructor new ClassNotFoundException() has explicty stated: 71 public ClassNotFoundException() { 72 super((Throwable)null); // Disallow initCause 73 } Which during initCause is producing mentioned exception: 454 public synchronized Throwable initCause(Throwable cause) { 455 if (this.cause != this) 456 throw new IllegalStateException("Can't overwrite cause with " + 457 Objects.toString(cause, "a null"), this); 458 if (cause == this) 459 throw new IllegalArgumentException("Self-causation not permitted", this); 460 this.cause = cause; 461 return this; 462 }
Ack. 1) Tomcat side. > 1314 } catch (IllegalStateException ise) { > 1315 ClassNotFoundException cnfe = new ClassNotFoundException(); > 1316 cnfe.initCause(ise); > 1317 throw cnfe; > 1318 } initCause() usually is used for compatibility for 1.3 and earlier versions of java that did not have a Throwable(Throwable cause) constructor. There is no ClassNotFoundException(Throwable) constructor, but there is (String, Throwable) one. Calling initCause() here is a recent code, introduced in r1596004 (17 months ago) with additional refactoring in r1640087. > > I belive the problem is caused by setting initcause on created class when > constructor > new ClassNotFoundException() > > has explicty stated: > > 71 public ClassNotFoundException() { > 72 super((Throwable)null); // Disallow initCause > 73 } The above nasty trick in JRE is old. E.g. 5u20 already has it... 2) The trigger for this behaviour is a bug in your own web application. You cannot load classes when the web application (and its class loader) has already been stopped. If you need help with fixing this bug in your application, ask on the users mailing list. Don't forget to provide version numbers and full stack trace. http://tomcat.apache.org/lists.html#tomcat-users http://markmail.org/message/ntwrtxeke4agdexj
No need, thanks. Trigger of this was inside hazelcast library. Hazelcast that loads class for itself called a function on ClassLoader which was expected to throw ClassNotFoundException in case of any problem. I believe that if ClassLoader would throw expected ClassNotFoundException the problem would not occur. However I am considering to report this to them as well as RuntimeException from any method should not cause the entire Hazelcast cluster to collapse - which is exactly what have happened because of the bug reported here and badly handling of runtime exceptions in Hazelcast. The problem was caused by deploy of new version of application when the previous was was not undeployed correctly by Tomcat.
Thanks for the report. This has been fixed in trunk and 8.0.x for 8.0.29 onwards.