3

直到今年 5 月,我一直在使用GWT 2.5.1简单的 DevMode,并且能够根据这篇精彩的文章将带有堆栈跟踪的混淆异常发送到服务器,并在那里使用符号映射对它们进行去混淆处理。这对我帮助很大。

自 6 月以来,我成功切换到GWT 2.6.1SuperDevMode ,与简单的 DevMode相比,它提供了相当不错的体验,并且使用起来更简单。

但是,我注意到我的堆栈跟踪不再在服务器上正确反混淆了。即使在去混淆之后,我也会不断得到混淆的堆栈跟踪。

以下是*.gwt.xml文件的相关内容:

<module rename-to="somemodule">

    <!-- inherits, stylesheet, entry-point, source elements are going here -->

    <add-linker name="xsiframe" />

    <extend-property name="locale" values="uk" />
    <set-property-fallback name="locale" value="uk" />

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

    <set-property name="gwt.logging.logLevel" value="INFO" />            
    <set-property name="gwt.logging.enabled" value="TRUE" />  
    <set-property name="gwt.logging.developmentModeHandler" value="ENABLED" />    
    <set-property name="gwt.logging.systemHandler" value="DISABLED" />  
    <set-property name="gwt.logging.popupHandler" value="DISABLED" />  
    <set-property name="gwt.logging.consoleHandler" value="ENABLED" />   
    <set-property name="gwt.logging.firebugHandler" value="ENABLED" />
</module>

以下是处理客户端异常的服务器端代码:

import static com.google.gwt.user.client.rpc.RpcRequestBuilder.STRONG_NAME_HEADER;
import com.google.gwt.core.client.impl.SerializableThrowable;
import com.google.gwt.logging.server.StackTraceDeobfuscator;

// ....

@Override
public void logClientException(final SerializableThrowable ex, final String userAgent, final String platform, final String moduleName) {
    final HttpServletRequest request = getThreadLocalRequest();

    final String symbolMapsDirectory = "webapps/" + getTomcatWebappFolder(request.getServletContext()) + "/WEB-INF/deploy/" + moduleName + "/symbolMaps";
    final String permutationName = request.getHeader(STRONG_NAME_HEADER);
    final Throwable original = new StackTraceDeobfuscator(symbolMapsDirectory).deobfuscateThrowable(ex.getThrowable(), permutationName);

    logClientException(original, userAgent, platform);
}

从GWT 2.5.1转移到GWT 2.6.1时我遗漏了什么吗?

非常感谢您的帮助!

4

2 回答 2

3

这是一个不幸的已知问题。见这里这里

问题是每次重新编译都会创建一个全新的增量目录树(参见 compile-1、compile-2 等子目录)。因此,正在运行的应用程序服务器(托管您的 servlet)将无法选择正确的compile-x/extras/<module-name>/symbolMaps目录来调用 setSymbolMapsDirectory(正如@Vadim 指出的那样)。当然,symbolMaps每次重新编译时都将其复制到预期的目录中是一个相当大的 PITA(我什至不确定它是否可以使用排列名称)。

GWT-RPC与 SuperDevMode 时代初期的情况相同,但不同之处在于 codeserver (SDM) 现在直接公开所有这些 *.gwt.rpc 输出文件,如果使用gwt.codeserver.portjava 标志,您的 servlet 将自动下载策略文件(仅在本地主机中,并且 GTW >= 2.5.1)。

无论如何,关键是让代码服务器也以某种方式公开/提供symbolMaps文件(这已经以某种方式通过http://localhost:9876/sourcemaps/<module-name>/gwtSourceMap.json但仅针对源映射而不是以StackTraceCreator可理解的方式进行),如第一个问题中所述。

幸运的是,堆栈跟踪在开发中并没有那么糟糕

于 2014-07-10T13:24:12.240 回答
2

就在昨天,我遇到了类似的问题。除了一个例外 - 我们在 GWT 日志记录中使用内置的反混淆功能。所以我的问题出在不正确的symbolMapsDirectory路径上。这里的坏消息是 GWT 不会告诉您您的 symbolMaps 路径是否不正确:

com.google.gwt.core.server.StackTraceDeobfuscator#loadSymbolMap:

try {
  BufferedReader bin = ...
} catch (IOException e) {
  // If the symbol map isn't found or there's an I/O error reading the file, the returned
  // mapping may contain some or all empty data (see below).
}

所以我们的工作解决方案如下所示:

setSymbolMapsDirectory(getServletContext().getRealPath("/WEB-INF/deploy/" + moduleName + "/symbolMaps/"));
于 2014-07-09T06:24:31.033 回答