Tomcatを停止して再起動すると、こんな例外が発生することがあります。
java.lang.ClassCastException: java.lang.StackTraceElement cannot be cast to java.lang.String at java.io.ObjectInputStream.readTypeString(ObjectInputStream.java:1421) at java.io.ObjectStreamClass.readNonProxy(ObjectStreamClass.java:719) at java.io.ObjectInputStream.readClassDescriptor(ObjectInputStream.java:833) at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1609) at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1521) at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1781) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1353) at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2018) at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1942) at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1808) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1353) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:373) at java.util.ArrayList.readObject(ArrayList.java:791) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1058) at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1909) at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1808) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1353) at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2018) at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1942) at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1808) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1353) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:373) at org.apache.catalina.session.StandardSession.doReadObject(StandardSession.java:1611) at org.apache.catalina.session.StandardSession.readObjectData(StandardSession.java:1077) at org.apache.catalina.session.StandardManager.doLoad(StandardManager.java:218) at org.apache.catalina.session.StandardManager.load(StandardManager.java:162) at org.apache.catalina.session.StandardManager.startInternal(StandardManager.java:356) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5196) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1403) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1393) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745)
Tomcatを停止した時にセッションを永続化し、再起動時に再ロードしているわけなんですがそれに失敗しています。 なにゆえStackTraceElementをStringにキャストしようとしているのかは謎ですが。。。そんなコード書いたっけ?
さて、とりあえず僕はセッションの永続化が不要なのでこの機能をOFFにしたい。
調べてみたところ、context.xmlを書く必要があるようです。
<?xml version="1.0" encoding="UTF-8"?> <Context> <!-- pathnameがnullの場合、永続化は無効 --> <Manager className="org.apache.catalina.session.StandardManager" pathname="" /> </Context>
マニュアルによると、
This persistence may be disabled by setting this attribute to an empty string.
だそうですが、あてにならないのでソースを読みます。
以下はorg.apache.catalina.session.StandardManagerのそれっぽい箇所を抜粋したもの。
protected void doUnload() throws IOException { if (log.isDebugEnabled()) log.debug(sm.getString("standardManager.unloading.debug")); if (sessions.isEmpty()) { log.debug(sm.getString("standardManager.unloading.nosessions")); return; // nothing to do } // Open an output stream to the specified pathname, if any File file = file(); if (file == null) { // nullなら何もせず終了 return; } ... } ... protected File file() { if (pathname == null || pathname.length() == 0) { return null; // pathnameがnullか空文字ならnullを返す } File file = new File(pathname); if (!file.isAbsolute()) { Context context = getContext(); ServletContext servletContext = context.getServletContext(); File tempdir = (File) servletContext.getAttribute(ServletContext.TEMPDIR); if (tempdir != null) { file = new File(tempdir, pathname); } } return file; }
見ての通り、pathnameがnullなら永続化をしないことが確認できたのでこれで正しいようです。