I have a class which has an init-method defined in xml
<bean id="appStarter" class="com.myapp.myClass" init-method="init" destroy-method="destroy"/>
myClass:
public class myClass{ private Thread t; public void init() { t = new Thread() { @Override public void run() { while (true) try { doStuff(); Thread.sleep(1000); } catch (Exception e) { e.printStackTrace(); } } }; t.start(); } public void destroy() { t.interrupt(); } }
When the app starts, these threads run fine, and everything works just fine and after sometime i get the following exception.
INFO: Illegal access: this web application instance has been stopped already. Could not load com.sun.mail.imap.IMAPStore. The eventual following stack trace is caused by an error thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access, and has no functional impact. java.lang.IllegalStateException at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1273) at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1233) at javax.mail.Session.getService(Session.java:755) at javax.mail.Session.getStore(Session.java:569) at javax.mail.Session.getStore(Session.java:531) at javax.mail.Session.getStore(Session.java:510)
in the doStuff method:
public void doStuff(){ Session sessioned = Session.getDefaultInstance(System.getProperties(), null); Store store = sessioned.getStore("imap"); store.connect(hostName, userName, password); . . . }
I don't know why, any ideas ?
Problem solved after restarting the tomcat and apache, the tomcat was caching older version of the app.
In short: this happens likely when you are hot-deploying webapps. For instance, your ide+development server hot-deploys a war again. Threads, that have been created previously are still running. But meanwhile their classloader/context is invalid and faces the IllegalAccessException / IllegalStateException becouse its orgininating webapp (the former runtime-environment) has been redeployed.
So, as states here, a restart does not permanently resolve this issue. Instead, it is better to find/implement a managed Thread Pool, s.th. like this to handle the termination of threads appropriately. In JavaEE you will use these ManagedThreadExeuctorServices. A similar opinion and reference here.
Examples for this are the EvictorThread of Apache Commons Pool, that "cleans" pooled instances according to the pool's configuration (max idle etc.).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With