読者です 読者をやめる 読者になる 読者になる

この日記は私的なものであり所属会社の見解とは無関係です。 GitHub: takahashikzn

ecjでコンパイルしたクラスをTomcat8でデプロイできない

Tomcat

実は、Tomcat-8.0.8から何故かこんなエラーが出て、WEBアプリが起動しなくなっていました。

6 26, 2014 8:14:41 午後 org.apache.catalina.startup.ContextConfig processAnnotationsWebResource
重大: Unable to process web resource [/WEB-INF/classes/foo/bar/AAA.class] for annotations
java.io.EOFException
	at java.io.DataInputStream.readUnsignedShort(DataInputStream.java:340)
	at org.apache.tomcat.util.bcel.classfile.Utility.swallowMethodParameters(Utility.java:188)
	at org.apache.tomcat.util.bcel.classfile.Attribute.readAttribute(Attribute.java:159)
	at org.apache.tomcat.util.bcel.classfile.FieldOrMethod.<init>(FieldOrMethod.java:76)
	at org.apache.tomcat.util.bcel.classfile.ClassParser.readMethods(ClassParser.java:226)
	at org.apache.tomcat.util.bcel.classfile.ClassParser.parse(ClassParser.java:101)
	at org.apache.catalina.startup.ContextConfig.processAnnotationsStream(ContextConfig.java:1987)
	at org.apache.catalina.startup.ContextConfig.processAnnotationsWebResource(ContextConfig.java:1897)
	at org.apache.catalina.startup.ContextConfig.processAnnotationsWebResource(ContextConfig.java:1892)
	at org.apache.catalina.startup.ContextConfig.processAnnotationsWebResource(ContextConfig.java:1892)
	at org.apache.catalina.startup.ContextConfig.processAnnotationsWebResource(ContextConfig.java:1892)
	at org.apache.catalina.startup.ContextConfig.processAnnotationsWebResource(ContextConfig.java:1892)
	at org.apache.catalina.startup.ContextConfig.processAnnotationsWebResource(ContextConfig.java:1892)
	at org.apache.catalina.startup.ContextConfig.processAnnotationsWebResource(ContextConfig.java:1892)
	at org.apache.catalina.startup.ContextConfig.processAnnotationsWebResource(ContextConfig.java:1892)
	at org.apache.catalina.startup.ContextConfig.webConfig(ContextConfig.java:1135)
	at org.apache.catalina.startup.ContextConfig.configureStart(ContextConfig.java:767)
	at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:302)
	at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
	at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
	at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5083)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1396)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1386)
	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-8.0.5に戻して見なかったフリをしてたのですが。。。

Tomcat8もとうとう正式リリースされたことですし、そうも言っていられなくなりました。

まずは答えから

ズバリ、Eclipse4.4から導入されたコンパイラオプション『引数の情報をキープしておく』が原因です。
これをOFFにしたら発生しなくなりました。

f:id:takahashikzn:20140626202349p:plain


ま、スタックトレースを見る限りクラスフォーマットに問題が有ることは明らか。
言うまでもありませんが、bcelバイトコードをいじるライブラリ。


それに、org.apache.catalina.startup.ContextConfigクラスのソースを見たところ、
Servlet-3.0仕様のアノテーションを見てイントロスペクションしている箇所でした。
(javax.servlet.annotation.WebServlet等)
一旦クラスロードしちまうと面倒なので、クラスローダーを使わずにbcelでクラスの情報を読んでいるってことですな。


というわけで、その辺りから原因を調べて行ったら意外と早く見つかりました。やれやれだぜ。
ま、Tomcatのソースもそれなりに眺めましたけどね。

ところで

やっぱ、Apacheプロジェクトのソースはキレイですね。スゲー読みやすい。