【问题标题】:GWT Remote Logging could not log Throwable Stacktrace?GWT 远程日志记录无法记录 Throwable Stacktrace?
【发布时间】:2014-03-06 12:29:48
【问题描述】:

我想使用 GWT Remote Logging。这就是我所做的:

在我的 web.xml 文件中我做了:

<servlet>
        <servlet-name>remoteLogging</servlet-name>
        <servlet-class>com.google.gwt.logging.server.RemoteLoggingServiceImpl</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>remoteLogging</servlet-name>
        <url-pattern>/web/remote_logging</url-pattern>
    </servlet-mapping> 

在我的 gwt.xml 文件中我做了:

 <module rename-to='web'>

 ...    

 <inherits name="com.google.gwt.logging.Logging" />
    <set-property name="gwt.logging.logLevel" value="INFO" />
    <set-property name="gwt.logging.enabled" value="TRUE" />
    <set-property name="gwt.logging.popupHandler" value="DISABLED" />
    <set-property name="gwt.logging.developmentModeHandler" value="ENABLED" />  
    <set-property name="gwt.logging.simpleRemoteHandler" value="ENABLED" />

我在 GWT Java 代码的某个地方做了:

Logger logger = Logger.getLogger("NameOfYourLogger");
logger.log(Level.SEVERE, "this message should get logged");

但是,当我尝试像这样记录堆栈跟踪(Throwable)时:

// Throwable throwable

LogRecord lr = new LogRecord(Level.SEVERE, "test");
lr.setThrown(throwable);
logger.log(lr);

我得到一个错误:

16:24:26.887 [ERROR] [web] Sun Feb 09 16:24:26 CET 2014 WireActivityLogger
SEVERE: Remote logging failed: 
com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException: java.lang.ClassCastException: com.google.gwt.core.client.impl.SerializableThrowable cannot be cast to com.google.gwt.core.shared.SerializableThrowable
    at com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException_FieldSerializer.instantiate(IncompatibleRemoteServiceException_FieldSerializer.java:16)
    at com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException_FieldSerializer.create(IncompatibleRemoteServiceException_FieldSerializer.java:25)
    at com.google.gwt.user.client.rpc.impl.SerializerBase.instantiate(SerializerBase.java:115)
    at com.google.gwt.user.client.rpc.impl.ClientSerializationStreamReader.deserialize(ClientSerializationStreamReader.java:396)
    at com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamReader.readObject(AbstractSerializationStreamReader.java:119)
    at com.google.gwt.user.client.rpc.impl.RequestCallbackAdapter.onResponseReceived(RequestCallbackAdapter.java:216)
    at com.google.gwt.http.client.Request.fireOnResponseReceived(Request.java:258)
    at com.google.gwt.http.client.RequestBuilder$1.onReadyStateChange(RequestBuilder.java:412)
    at sun.reflect.GeneratedMethodAccessor103.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:103)
    at com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)
    at com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:172)
    at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessagesWhileWaitingForReturn(BrowserChannelServer.java:338)
    at com.google.gwt.dev.shell.BrowserChannelServer.invokeJavascript(BrowserChannelServer.java:219)
    at com.google.gwt.dev.shell.ModuleSpaceOOPHM.doInvoke(ModuleSpaceOOPHM.java:136)
    at com.google.gwt.dev.shell.ModuleSpace.invokeNative(ModuleSpace.java:571)
    at com.google.gwt.dev.shell.ModuleSpace.invokeNativeObject(ModuleSpace.java:279)
    at com.google.gwt.dev.shell.JavaScriptHost.invokeNativeObject(JavaScriptHost.java:91)
    at com.google.gwt.core.client.impl.Impl.apply(Impl.java)
    at com.google.gwt.core.client.impl.Impl.entry0(Impl.java:242)
    at sun.reflect.GeneratedMethodAccessor101.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:103)
    at com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)
    at com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:172)
    at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessages(BrowserChannelServer.java:293)
    at com.google.gwt.dev.shell.BrowserChannelServer.processConnection(BrowserChannelServer.java:547)
    at com.google.gwt.dev.shell.BrowserChannelServer.run(BrowserChannelServer.java:364)
    at java.lang.Thread.run(Thread.java:722)

如何远程记录堆栈跟踪?

编辑:我也试过了

// Throwable throwable
LogRecord lr = new LogRecord(Level.SEVERE, throwable.toString());
logger.log(lr);

// Throwable throwable
LogRecord lr = new LogRecord(Level.SEVERE, throwable.getMessage());
logger.log(lr);

但我收到以下错误:

| Error 2014-02-19 02:21:04,017 [http-nio-8080-exec-7] ERROR [localhost].[/test]  - Exception while dispatching incoming RPC call
Message: Service method 'public abstract java.lang.String com.google.gwt.logging.shared.RemoteLoggingService.logOnServer(java.util.logging.LogRecord)' threw an unexpected exception: java.lang.NullPointerException
    Line | Method
->>  389 | encodeResponseForFailure in com.google.gwt.user.server.rpc.RPC
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|    579 | invokeAndEncodeResponse  in     ''
|    265 | processCall . . . . . .  in com.google.gwt.user.server.rpc.RemoteServiceServlet
|    305 | processPost              in     ''
|     62 | doPost . . . . . . . . . in com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet
|     46 | doFilterInternal         in org.grails.jaxrs.web.JaxrsFilter
|     70 | doFilter . . . . . . . . in com.github.greengerong.PreRenderSEOFilter
|   1145 | runWorker                in java.util.concurrent.ThreadPoolExecutor
|    615 | run . . . . . . . . . .  in java.util.concurrent.ThreadPoolExecutor$Worker
^    722 | run                      in java.lang.Thread
Caused by NullPointerException: null
->>  262 | hash                     in java.util.Hashtable
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|    459 | get                      in     ''
|    489 | findLogger . . . . . . . in java.util.logging.LogManager$LoggerContext
|    910 | getLogger                in java.util.logging.LogManager
|    400 | demandLogger . . . . . . in     ''
|    317 | demandLogger             in java.util.logging.Logger
|    361 | getLogger . . . . . . .  in     ''
|     62 | logOnServer              in com.google.gwt.logging.server.RemoteLoggingServiceUtil
|     46 | logOnServer . . . . . .  in com.google.gwt.logging.server.RemoteLoggingServiceImpl
|    561 | invokeAndEncodeResponse  in com.google.gwt.user.server.rpc.RPC
|    265 | processCall . . . . . .  in com.google.gwt.user.server.rpc.RemoteServiceServlet
|    305 | processPost              in     ''
|     62 | doPost . . . . . . . . . in com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet
|     46 | doFilterInternal         in org.grails.jaxrs.web.JaxrsFilter
|     70 | doFilter . . . . . . . . in com.github.greengerong.PreRenderSEOFilter
|   1145 | runWorker                in java.util.concurrent.ThreadPoolExecutor
|    615 | run . . . . . . . . . .  in java.util.concurrent.ThreadPoolExecutor$Worker
^    722 | run                      in java.lang.Thread

编辑:

这是我使用的代码:

import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;

new AsyncCallback<GetResults<ItemDto>>() {


            @Override
            public void onFailure(Throwable e) {
                Logger logger = Logger.getLogger("test");
                logger.log(Level.SEVERE, "this message should get logged");

                LogRecord lr = new LogRecord(Level.SEVERE, e.toString());
                logger.log(lr);

            }

            ...

}

【问题讨论】:

  • InvocationException: 然后呢?您的模块的名称是什么(根据您的 web.xml,它应该是 web)?您的服务器日志中有任何输出吗?
  • @ColinAlworth 我更新了我的问题日志记录,适用于字符串,但不适用于 Throwable,正如我指出的那样。有什么想法吗?

标签: java javascript gwt servlets grails


【解决方案1】:

考虑记录异常堆栈跟踪:

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

stacktrace和异常处理如下:

  1. http://www.summa-tech.com/blog/2012/06/11/7-tips-for-exception-handling-in-gwt/

  2. https://code.google.com/p/google-web-toolkit/wiki/WebModeExceptions

【讨论】:

    【解决方案2】:

    将 SerializableThrowable 从 client.impl 库转换为 core.shared 库时,您会遇到异常。似乎您只是希望将问题作为字符串写入日志。我从来没有使用过这个类(只是从文档中阅读),你尝试过以下...

    // Throwable throwable
    LogRecord lr = new LogRecord(Level.SEVERE, throwable.toString());
    logger.log(lr);
    

    // Throwable throwable
    LogRecord lr = new LogRecord(Level.SEVERE, throwable.getMessage());
    logger.log(lr);
    

    如果这不起作用,您可能会发现以下链接很有帮助:

    http://www.summa-tech.com/blog/2012/06/11/7-tips-for-exception-handling-in-gwt/

    请注意,在上面的 URL 中,在技巧 4 中,作者将他的程序设置为与您的相同。但他在最后一段中警告说......

    "[在服务器上记录异常] 看起来很简单,对吧?小心!首先,不是所有的异常 是可序列化的或遵循可序列化的规则(啊!)。为了 例如,GWT 的 JavascriptException 继承了 Serializable,但没有 实现一个公共的无参数构造函数,所以当你尝试发送这个 通过您的 RPC 通过网络,运行时序列化异常是 抛出。并且由于此异常会在您的异常中引发 处理程序,它会有效地吞下。二、堆栈跟踪 异常内是瞬态的,因此 [it] 从客户端到服务器丢失 (因此,如果您在服务器端需要它,请将其作为单独的 范围)。这让我想到了下一个技巧……”

    在段落中,他说明了您遇到的确切原始问题 - 并非所有异常都是可序列化的,因此可能会引发序列化异常(这也可以解释为什么当您尝试输出抛出的错误消息时,可抛出对象为空AsyncCallback 类的 onFailure 方法)。然后继续阅读技巧 5 和 6。

    这些链接也可能有用...

    Best Practices for GWT services exceptions logging

    http://cleancodematters.com/2011/05/29/improved-exceptionhandling-with-gwts-requestfactory/

    【讨论】:

    • 我尝试了您的解决方案,但失败了。我在我的问题中发布了错误。还有其他想法吗?
    • @confile 是否有一个名为 thowable 的 Throwable 对象定义为您的评论指出的?听起来它是空的,当它被添加为 LogRecord 的第二个参数时,它会导致空指针异常。
    • 我发布了我正在使用的代码。 Throwable 不为空。
    • @confile,请参阅我编辑的答案,其中包括我最初发布的 URL 的摘录,您可能会觉得有帮助。
    【解决方案3】:

    查看您收到的错误,您的 GWT 应用似乎正在发送 com.google.gwt.core.client.impl.SerializableThrowable 的实例,但您的服务器正在等待 com.google.gwt.core.shared.SerializableThrowable 的实例。

    在我们的项目中,我们仍然使用 GWT 2.5,我们在 SDK 中的类是第一个。

    似乎 GWT 2.6 引入了第二个并弃用了另一个。也许您的客户端和您的服务器不在完全相同的 GWT 版本上?或者您的客户端代码以某种方式使用了错误的 SerializableThrowable。

    另外,我注意到这里有两个属性,但您没有在 GWT 配置中提及:

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

    【讨论】:

      猜你喜欢
      • 2020-12-09
      • 1970-01-01
      • 2021-06-06
      • 1970-01-01
      • 1970-01-01
      • 2016-01-07
      • 1970-01-01
      • 2020-11-19
      • 1970-01-01
      相关资源
      最近更新 更多