ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

Apache Tapestryコミュの[T5] @InjectPageによる不具合

  • mixiチェック
  • このエントリーをはてなブックマークに追加
ここはお前の予備校じゃないぞ、と、そろそろ怒られてしまいそうですが、懲りずに質問させていただきます。(^^;

本日、あるコンポーネントの中で、「@InjectPage」を使用したところ、「StackMapTable format error: bad class index」なるエラーが出てしまいました。

経験的に、このエラーが出る時は原因がつかみにくいのですが、今日は絞り込んだ結果、「@InjectPage」を書くとエラーが出る、と言うところまではたどり着きました。

いくつかのページを試してみましたが、ページを問わず「@InjectPage」を使うとエラーが出るようです。

自分のコードに絶対の自信がある訳ではないのですが、「@InjectPage」にまつわる問題等は確認されていますでしょうか?

Tapestryのバージョンは5.0.5です。

長くて申し訳ありませんが、エラー時にブラウザに表示されたトレースを書かせていただきます。
なにかお気づきの点がありましたら、ご指摘ください。


An unexpected application exception has occurred.

* org.apache.tapestry.ioc.internal.util.TapestryException
StackMapTable format error: bad class index

location
 context:WEB-INF/config/AddConfig.html, line 4, column 23
  1 <t:layouts.withmenu xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
  2
  3 <t:layouts.input>
  4 <t:config.configform/>
  5 </t:layouts.input>
  6
  7 <t:config.function/>
  8
  9 </t:layouts.withmenu>

* org.apache.tapestry.internal.services.TransformationException
StackMapTable format error: bad class index

transformation

InternalClassTransformation[
public com.example.sample.components.config.ConfigForm extends com.example.sample.base.AbstractForm

add method: private void _$write_messages_0(org.apache.tapestry.ioc.Messages $1)
throw new java.lang.RuntimeException("Field com.example.sample.components.config.ConfigForm._messages is read-only.");

replace write _messages: _$write_messages_0();

add method: private void _$write_db(com.example.sample.services.DbAccess $1)
throw new java.lang.RuntimeException("Field com.example.sample.components.config.ConfigForm._db is read-only.");

replace write _db: _$write_db();

add field: protected final org.apache.tapestry.internal.services.RequestPageCache _$requestPageCache;

add method: private com.example.sample.pages.common.PrivateDBError _$read_inject_page_error()
{
org.apache.tapestry.internal.structure.Page page = _$requestPageCache.get("common/PrivateDBError");return (com.example.sample.pages.common.PrivateDBError) page.getRootElement().getComponent();
}


replace read _error: _$read_inject_page_error();

add method: private void _$write_error(com.example.sample.pages.common.PrivateDBError $1)
throw new java.lang.RuntimeException("Field com.example.sample.components.config.ConfigForm._error is read-only.");

replace write _error: _$write_error();

remove field _error;

convert default constructor: initializer_0();

add constructor: com.example.sample.components.config.ConfigForm(org.apache.tapestry.internal.InternalComponentResources $1, com.example.sample.services.DbAccess $2, org.apache.tapestry.internal.services.RequestPageCache $3)
{ super($1);
_messages = _$resources.getMessages();
_db = $2;
_$requestPageCache = $3;
initializer_0();

}

]

* java.lang.ClassFormatError
StackMapTable format error: bad class index

Stack trace
・java.lang.Class.getDeclaredConstructors0(Native Method)
・java.lang.Class.privateGetDeclaredConstructors(Unknown Source)
・java.lang.Class.getConstructors(Unknown Source)
・org.apache.tapestry.internal.services.ReflectiveInstantiator.findConstructor(ReflectiveInstantiator.java:65)
・org.apache.tapestry.internal.services.ReflectiveInstantiator.<init>(ReflectiveInstantiator.java:53)
・org.apache.tapestry.internal.services.InternalClassTransformationImpl.createInstantiator(InternalClassTransformationImpl.java:1227)
・org.apache.tapestry.internal.services.ComponentClassTransformerImpl.createInstantiator(ComponentClassTransformerImpl.java:157)
・org.apache.tapestry.internal.services.ComponentInstantiatorSourceImpl.findInstantiator(ComponentInstantiatorSourceImpl.java:242)
・org.apache.tapestry.internal.services.PageElementFactoryImpl.newComponentElement(PageElementFactoryImpl.java:268)
・org.apache.tapestry.internal.services.PageLoaderProcessor.startComponent(PageLoaderProcessor.java:618)
・org.apache.tapestry.internal.services.PageLoaderProcessor.loadTemplateForComponent(PageLoaderProcessor.java:498)
・org.apache.tapestry.internal.services.PageLoaderProcessor.workComponentQueue(PageLoaderProcessor.java:714)
・org.apache.tapestry.internal.services.PageLoaderProcessor.loadPage(PageLoaderProcessor.java:392)
・org.apache.tapestry.internal.services.PageLoaderImpl.loadPage(PageLoaderImpl.java:59)
・org.apache.tapestry.internal.services.PagePoolImpl.checkout(PagePoolImpl.java:70)
・org.apache.tapestry.internal.services.RequestPageCacheImpl.get(RequestPageCacheImpl.java:44)
・com.example.sample.components.config.ConfigFunction._$read_inject_page_add(ConfigFunction.java)
・com.example.sample.components.config.ConfigFunction.onActionFromAddFlag(ConfigFunction.java:47)
・com.example.sample.components.config.ConfigFunction.handleComponentEvent(ConfigFunction.java)
・org.apache.tapestry.internal.structure.ComponentPageElementImpl.handleEvent(ComponentPageElementImpl.java:885)
・org.apache.tapestry.internal.structure.ComponentPageElementImpl.triggerEvent(ComponentPageElementImpl.java:998)
・org.apache.tapestry.internal.services.ComponentActionRequestHandlerImpl.handle(ComponentActionRequestHandlerImpl.java:81)
・org.apache.tapestry.internal.services.InternalModule$11.handle(InternalModule.java:541)
・org.apache.tapestry.internal.services.ComponentActionDispatcher.dispatch(ComponentActionDispatcher.java:116)
・org.apache.tapestry.services.TapestryModule$12.service(TapestryModule.java:1066)
・com.example.sample.services.AppModule$3.service(AppModule.java:168)
・com.example.sample.services.AppModule$1.service(AppModule.java:58)
・org.apache.tapestry.internal.services.LocalizationFilter.service(LocalizationFilter.java:43)
・org.apache.tapestry.services.TapestryModule$2.service(TapestryModule.java:657)
・org.apache.tapestry.internal.services.StaticFilesFilter.service(StaticFilesFilter.java:63)
・org.apache.tapestry.internal.services.CheckForUpdatesFilter$2.invoke(CheckForUpdatesFilter.java:97)
・org.apache.tapestry.internal.services.CheckForUpdatesFilter$2.invoke(CheckForUpdatesFilter.java:88)
・org.apache.tapestry.ioc.internal.util.ConcurrentBarrier.withRead(ConcurrentBarrier.java:77)
・org.apache.tapestry.internal.services.CheckForUpdatesFilter.service(CheckForUpdatesFilter.java:110)
・org.apache.tapestry.services.TapestryModule$11.service(TapestryModule.java:1044)
・org.apache.tapestry.TapestryFilter.doFilter(TapestryFilter.java:135)
・org.mortbay.jetty.servlet.WebApplicationHandler$CachedChain.doFilter(WebApplicationHandler.java:821)
・org.mortbay.jetty.servlet.WebApplicationHandler.dispatch(WebApplicationHandler.java:471)
・org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:568)
・org.mortbay.http.HttpContext.handle(HttpContext.java:1530)
・org.mortbay.jetty.servlet.WebApplicationContext.handle(WebApplicationContext.java:633)
・org.mortbay.http.HttpContext.handle(HttpContext.java:1482)
・org.mortbay.http.HttpServer.service(HttpServer.java:909)
・org.mortbay.http.HttpConnection.service(HttpConnection.java:820)
・org.mortbay.http.HttpConnection.handleNext(HttpConnection.java:986)
・org.mortbay.http.HttpConnection.handle(HttpConnection.java:837)
・org.mortbay.http.SocketListener.handleConnection(SocketListener.java:245)
・org.mortbay.util.ThreadedServer.handle(ThreadedServer.java:357)
・org.mortbay.util.ThreadPool$PoolThread.run(ThreadPool.java:534)

コメント(5)

こればっかりやっていた訳ではないのですが、まだ解決を見ていません。

試しに5.0.6にバージョンアップしてみましたが、全く同じエラーがでました。
また、別のコンポーネントで、やはり@InjectPageを書くとエラーになる症状が出ました。
このコンポーネントでは、@ApplicationStateも駄目でした。

私のコードに問題があると思うのですが、スタックトレースからなにか読み取る事はできるでしょうか。
問題解決のポイント等がありましたら、ご教示ください。
毎回、的確な情報をありがとうございます。
Tapestry users MLの公式アーカイバ(と私が思っているところ)は、全文検索ができないのが使いづらいな、と思っていたのですが、今回教えていただいたURLは、まさに私のニーズにぴったりのものです。

今日、かなりの時間をこの問題のために割きましたが、結論から言うと、Javassistを3.6.0.CR1にすると、@InjectPageは通るようになったのですが、@ApplicationStateは別のエラーが出ました(意味も興味もないかもしれませんが、別掲でこのときのトレースを添付させていただきます)。
また、今まで問題なく動作していたコードが動かなくなるなど、MLでのやりとり通りのような症状がでたので、ひとまずJavassistはもとのバージョンに戻しておきました。

rakuさんのコメントから、JDK1.5では問題がないように見受けられました(私はご推察通り1.6を使っていました)ので、JDKのバージョンを下げようと試みたのですがそれも上手く行きませんでした。
というのも、私は開発にEclipse3.3を使っているのですが、最初にTapestryをEclipse上で動作させるために、1.6でないと動かなかった経緯がありまして。
今回改めて1.5を試して見たのですが、「ワークスペースが互換性がない」みたいな警告(ちゃんと書きとめてくるべきでした)がでて、実行時環境として1.5を指定できませんでした。
この件については、明日もう少し掘り下げてみます。

せっかくTapestryも行けそうかな、という手応えを感じていたのですが、ここがクリアできないと「Tapestryは使えます」という報告はできないかなあ、と感じています。
もう少し頑張ります。

以下、トレースです。
An unexpected application exception has occurred.

* org.apache.tapestry.ioc.internal.util.TapestryException
 java.lang.ClassNotFoundException: caught an exception while obtaining a class file for com.example.sample.components.config.ConfigForm

location
 context:WEB-INF/config/EditConfig.html, line 4, column 23
 1 <t:layouts.withmenu xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
 2
 3 <t:layouts.input>
 4  <t:config.configform/>
 5 </t:layouts.input>
 6
 7 <t:config.function/>
 8
 9 </t:layouts.withmenu>

* java.lang.ClassNotFoundException
 caught an exception while obtaining a class file for com.example.sample.components.config.ConfigForm

exception
 org.apache.tapestry.internal.services.TransformationException: 3

* org.apache.tapestry.internal.services.TransformationException
 3

transformation

InternalClassTransformation[
public com.example.sample.components.config.ConfigForm extends com.example.sample.base.AbstractForm

add field: protected final org.apache.tapestry.services.ApplicationStateManager _$applicationStateManager_2;

add field: protected final java.lang.Class _$session_type_2;

add method: private com.example.sample.base.PageSession _$read_session_2()
return (com.example.sample.base.PageSession) _$applicationStateManager_2.get(_$session_type_2);

replace read _session: _$read_session_2();

add method: private void _$write_session_2(com.example.sample.base.PageSession $1)
_$applicationStateManager_2.set(_$session_type_2, $1);

replace write _session: _$write_session_2();

remove field _session;

add method: private void _$write_messages_3(org.apache.tapestry.ioc.Messages $1)
throw new java.lang.RuntimeException("Field com.example.sample.components.config.ConfigForm._messages is read-only.");

replace write _messages: _$write_messages_3();

add method: private void _$write_db_2(com.example.sample.services.DbAccess $1)
throw new java.lang.RuntimeException("Field com.example.sample.components.config.ConfigForm._db is read-only.");

replace write _db: _$write_db_2();

add field: protected final org.apache.tapestry.internal.services.RequestPageCache _$requestPageCache_2;

add method: private com.example.sample.pages.common.PrivateDBError _$read_inject_page_error_2()
{
 org.apache.tapestry.internal.structure.Page page = _$requestPageCache_2.get("common/PrivateDBError");return (com.example.sample.pages.common.PrivateDBError) page.getRootElement().getComponent();
}


replace read _error: _$read_inject_page_error_2();

add method: private void _$write_error_2(com.example.sample.pages.common.PrivateDBError $1)
throw new java.lang.RuntimeException("Field com.example.sample.components.config.ConfigForm._error is read-only.");

replace write _error: _$write_error_2();

remove field _error;

]

* java.lang.ArrayIndexOutOfBoundsException
 3

Stack trace
・javassist.bytecode.ByteArray.write16bit(ByteArray.java:40)
(以下略)
お世話様です。

本日、七転八倒したあげく、なんとかJDKを1.5にダウングレードし、問題は解決を見ました。
Eclipseのコンパイラの設定に気づかなかったのが敗因のようです。

1.5でリビルドしたところ、@InjectPageも@ApplicationStateも問題なく動くようになりました。
というわけで、今回の原因はJDK1.6とJavassistの相性にあったようです。

貴重な情報を本当にありがとうございました。
これでもう少し頑張れそうです。

ログインすると、みんなのコメントがもっと見れるよ

mixiユーザー
ログインしてコメントしよう!

Apache Tapestry 更新情報

Apache Tapestryのメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。

人気コミュニティランキング