4

を使用しGWTて、サーバーをTomcatにデプロイしました。これは正常に機能しますがGWT、例外をスローすると、ポップアップがクライアントに例外のスタックトレースを表示します。

開発モードでは、これは正常に機能します。Tomcatでは、以下のスタックトレースを取得します。

なぜ、どのようにこれを修正しますか?

Unknown.Le(StackTraceCreator.java:168)
Unknown.Jd(StackTraceCreator.java:421)
Unknown.NT(Exception_FieldSerializer.java:16)
Unknown.g1(SerializerBase.java:55)
Unknown.b1(SerializerBase.java:112)
Unknown.D$(AbstractSerializationStreamReader.java:119)
Unknown.uAc(CustomException_FieldSerializer.java:39)
Unknown.uBc(ServerSideException_FieldSerializer.java:12)
Unknown.f1(SerializerBase.java:46)
Unknown._0(SerializerBase.java:92)
Unknown.D$(AbstractSerializationStreamReader.java:119)
Unknown.B_(RequestCallbackAdapter.java:216)
Unknown._o(Request.java:287)

@Christian Kuetbachの答えを使用した後、これが私が今得たものです:

Unknown.com_google_gwt_core_client_impl_StackTraceCreator $ CollectorEmulated_ $ fillInStackTrace__Lcom_google_gwt_core_client_impl_StackTraceCreator $ CollectorEmulated_2Ljava_lang_Throwable_2V(StackTraceCreator.java:168)Unknown.java_lang_Throwable_Throwable__Ljava_lang_String_2Ljava_lang_Throwable_2V(StackTraceCreator.java:421)Unknown.com_google_gwt_user_client_rpc_StatusCodeException_StatusCodeException__ILjava_lang_String_2V(StatusCodeException.java:35)Unknown.com_google_gwt_user_client_rpc_impl_RequestCallbackAdapter_ $ onResponseReceived__Lcom_google_gwt_user_client_rpc_impl_RequestCallbackAdapter_2Lcom_google_gwt_http_client_Request_2Lcom_google_gwt_http_client_Response_2V(RequestCallbackAdapter.java:209)不明。com_google_gwt_http_client_Request_ $ fireOnResponseReceived__Lcom_google_gwt_http_client_Request_2Lcom_google_gwt_http_client_RequestCallback_2V(Request.java:287)Unknown.com_google_gwt_http_client_RequestBuilder $ 1_onReadyStateChange__Lcom_google_gwt_xhr_

助けてください!

4

3 に答える 3

5

なんで?

Christian Kuetbachが言ったように、これはDevMode(コードがJavaで実行される)とprodモード(コードがJavaScriptにコンパイルされ、クラスとメソッドの名前変更を含む最適化される)で実行することの違いです。

これをどのように修正しますか?

あなたはそうしない。一般的に、スタックトレースをユーザーに表示することはお勧めできません。例外をサーバーに送信してログに記録する方がはるかに優れています(たとえば、ログを使用java.util.loggingしてログSimpleRemoteLogHandlerをサーバーに送信し、サーバーにログを送信しますjava.util.logging)。

ただし、スタックトレースの難読化を解除する方法はいくつかあり、RemoteLoggingServiceImplサーブレットはそれを自動的に実行するように構成できます。厄介な詳細については、 http:
//code.google.com/p/google-web-toolkit/wiki/WebModeExceptionsを 参照してください。

リモートロギングを使用できない、または使用したくない場合は、スタックトレースを「手動で」難読化解除できます。順列(デフォルトの場所、GWTコンパイラにWEB-INF/deploy渡すことで変更できます)のファイルを確認します(ブラウザによってロードされたファイル-deployと同じ名前)、メソッドがどのJavaメソッドから発生したかを示します。 しかし、あなたはすでにソースファイル名と行番号を持っているので、本当にそれは必要ありませんよね?*.cache.*Le

于 2012-07-27T15:02:50.363 に答える
5

難読化解除されたロギングをセットアップするために必要な GWT ドキュメントのすべての情報を見つけるのは少し難しいので、ここに短いバージョンを示します。

モジュール ファイル (.gwt.xml) で、次を追加します。

<inherits name="com.google.gwt.logging.Logging"/>
<set-property name="gwt.logging.simpleRemoteHandler" value="ENABLED" />
<set-property name="compiler.stackMode" value="emulated" />
<set-configuration-property name="compiler.emulatedStack.recordLineNumbers" 
     value="true" />

クライアント側では、次のようなものを使用します

import java.util.logging.Logger;

private static Logger rootLogger = Logger.getLogger("");
...
rootLogger.log(Level.SEVERE, "My message", e);

RemoteLoggingServiceAsyncクライアント側でインスタンスを作成する必要はありません。指定したため、ロガーによって自動的に使用されます<set-property name="gwt.logging.simpleRemoteHandler" value="ENABLED" />

サーバー側で、RemoteLoggingServiceImpl を構成します。GWTコンパイラ引数でコンパイルするときに生成されるsymbolMapsの場所を指定する必要があります-extra /path/to/myExtraDir。私は個人的にこのアプローチを使用して RemoteLoggingServiceImpl をオーバーライドし、web.xml の [*] からディレクトリを指定できるようにし<init-param>ます

package mypackage.server;

public class ConfigurableRemoteLoggingServiceImpl extends RemoteLoggingServiceImpl {

  @Override
  public void init(final ServletConfig config) throws ServletException {
    super.init(config);

    final String symbolMapsDirectory = 
        config.getInitParameter("symbolMapsDirectory");
    setSymbolMapsDirectory(symbolMapsDirectory);
  }
}

web.xml、次のように登録します

<servlet>
    <servlet-name>remoteLogging</servlet-name>
    <servlet-class>mypackage.server.ConfigurableRemoteLoggingServiceImpl</servlet-class>

  <init-param>
    <param-name>symbolMapsDirectory</param-name>
    <param-value>/path/to/myExtraDir/mymodulename/symbolMaps</param-value>
  </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>remoteLogging</servlet-name>
    <url-pattern>/mymodulename/remote_logging</url-pattern>
</servlet-mapping>

とを独自の値に置き換え/path/to/myExtraDir引数を指定して GWT コンパイラを呼び出すことを忘れないでください(または詳細を使用する必要がないことに注意してください。OBF でも機能します)。生成されたすべてのシンボル マップを保持する: それらがないと、難読化解除は機能しません。すべての新しいバージョンには自動的に一意の名前が付けられるため、ビルド時にすべてを安全な中央の場所に集めることができます。mymodulenamemypackage-extra-style PRETTY

[*] そして、RemoteLoggingServiceImpl がそれ自体を実装しないのはなぜだろうか!

于 2012-07-29T10:46:49.153 に答える
1

最適化によってメソッド名とクラス名が削除されるため、これは期待どおりに機能します。

PRETTYまたはDetailedとしてコンパイルして、より読みやすいスタックトレースを取得できます。

Stacktracesをエミュレートする可能性もあります。

<set-property name="compiler.emulatedStack" value="true"/> 
<set-configuration-property name="compiler.emulatedStack.recordLineNumbers" value="true"/>
<set-configuration-property name="compiler.emulatedStack.recordFileNames" value="true"/> 

これは、JavaScriptのサイズが大きくなるため、本番環境での使用にはお勧めできません。

更新: Exception_FieldSerializer例外が表示されます。

シリアル化できないものをシリアル化しようとしていますか?

デフォルトのコンストラクターがないクラスはシリアル化できません。クライアントまたは共有パッケージ内にないクラス。例外をシリアル化しようとすると、これが問題になる可能性があります。

于 2012-07-27T13:28:37.737 に答える