java Thread ServletContextListener java.lang.IllegalStateException: Illegal access: this web application instance has been stopped already. Could not load

這個錯誤發生的原因, 在 tomcat 的 web.xml 中增加了一個 listener:

<listener>
       <listener-class>com.site.cron.QuartzListener</listener-class>
   </listener>

然後, 想寫排程的程式, 來存取資料庫的時候, 程式會顯示錯誤訊息:

Exception in thread "Thread-52" java.lang.IllegalStateException: Illegal access: this web application instance has been stopped already. Could not load [META-INF/services/javax.sql.rowset.RowSetFactory]. The following stack trace is thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access.
  at org.apache.catalina.loader.WebappClassLoaderBase.checkStateForResourceLoading(WebappClassLoaderBase.java:1432)
  at org.apache.catalina.loader.WebappClassLoaderBase.findResources(WebappClassLoaderBase.java:1003)
  at org.apache.catalina.loader.WebappClassLoaderBase.getResources(WebappClassLoaderBase.java:1110)
  at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.nextProviderClass(ServiceLoader.java:1203)
  at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.hasNextService(ServiceLoader.java:1228)
  at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.hasNext(ServiceLoader.java:1273)
  at java.base/java.util.ServiceLoader$2.hasNext(ServiceLoader.java:1309)
  at java.base/java.util.ServiceLoader$3.hasNext(ServiceLoader.java:1393)
  at java.sql.rowset/javax.sql.rowset.RowSetProvider.loadViaServiceLoader(RowSetProvider.java:291)
  at java.sql.rowset/javax.sql.rowset.RowSetProvider.newFactory(RowSetProvider.java:153)

解法, 很簡單, 關閉 web server 正常啟動一次就可以了.

相關討論串:

It looks like your quartz job is trying to do something after your app was stopped. It might be trying to access some resources that were available while your app was running, but not anymore (something like getResourceAsStream maybe).

It might help if you post more info: stacktraces, code of your job, etc.

After update: Here is what I think is happening:

  • You schedule your job successfully
  • For whatever reason your webapp is stopped. I would search JBoss logs for a reason.
  • At this moment time comes to execute your job (org.quartz.simpl.RAMJobStore.triggerFired(RAMJobStore.java:1313))
  • This call goes down to isStateful method of JobDetail class
  • The method has this code in it return (StatefulJob.class.isAssignableFrom(jobClass));
  • StatefulJob class was not loaded before. Your classLoader tries to load it (org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1204))
  • Since your webapp was stopped, you are getting exception

The way I see it, you have two choices:

  • Ignore this problem, since there is nothing you can do to make quartz work after your webapp was stopped
  • Try to figure out what causes your webapp to stop and fix it

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *