一尘不染

Tomcat为什么无法显示实际的堆栈跟踪?

tomcat

使用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_RequestCallback_2V(Request.java:287)Unknown.com_google_gwt_http_client_RequestBuilder
$ 1_onReadyStateChange_L。

请帮忙!


阅读 297

收藏
2020-06-16

共1个答案

一尘不染

在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。您将不得不告诉它,它在哪里找到symbolMaps,它将在使用GWT编译器参数进行编译时生成-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/myExtraDirmymodulenamemypackage用自己的价值观,不要忘记调用与GWT编译器-extra参数(请注意,您不必使用-style PRETTY或详细,它也与OBF的作品)。保留所有生成的symbolMap:如果没有它们,消除混淆将不起作用。由于每个新版本都会自动获得唯一的名称,因此您在构建时可以将它们全部收集在安全的中央位置。

[*]我真的,真的很奇怪,为什么RemoteLoggingServiceImpl本身没有实现!

2020-06-16