GWT,NoSuchElement异常

3
我们在一个大型项目中使用GWT。在某些情况下,这个代码可能会产生NoSuchElementException异常:
for (Object o: myList) {
}

里面没有对ArrayList进行修改。

但是这是最近才发生的。

在生成的应用程序源代码中,我发现:

var context, context$iterator, operation;
operation = doDeserialize(this$static, ctx, json);
for (context$iterator =
    new java_util_AbstractList$IteratorImpl_AbstractList$IteratorImpl__Ljava_util_AbstractList_2V(this$static.jetbrains_jetpad_otmodel_ot_persistence_OperationPersistenceContext_myContextDelegates);
    context$iterator.java_util_AbstractList$IteratorImpl_i < context$iterator.java_util_AbstractList$IteratorImpl_this$0.size__I();
) {
    context = java_util_AbstractList$IteratorImpl_$next__Ljava_util_AbstractList$IteratorImpl_2Ljava_lang_Object_2(context$iterator);
}

首先,这段代码返回true:iterator.i < iterator.size(); 但是在下一行(在 .next()中),这段代码也会返回true:iterator.i >= iterator.size();

我只能在Chrome中重现此问题。


如果您认为发现了一个 bug,并且假设您正在使用最新版本,请在 https://code.google.com/p/google-web-toolkit/issues/entry 上提交问题。 - Thomas Broyer
我是GWT的贡献者,我不确定它是否是一个bug,因为我无法理解它怎么可能会出现 :-( - AKonst
1个回答

0

我相信这是Chrome的JavaScript实现中的一个bug。它很少在常见的代码路径中出现,所以我怀疑这是一个微妙的时间问题。自Chrome 29.0.1547.57以来一直存在。

我们的客户在Chrome的最近几个版本中每天都会看到几个这样的实例。但我们自己无法复制它,也找不到导致<和>=表现出这种方式的值。

你是我见过的第一个遇到这个问题的人。

一个猜测是i的值没有立即从原型传递到新对象。(我们多年前在Firefox中看到了类似的问题。)您可以尝试调整AbstractList$IteratorImpl以在构造函数中显式设置i=0,这可能足以防止触发错误。(我们还没有在生产中尝试过这个方法,我们希望它能得到修复。)

我们在像PopupPanel这样的地方看到了这个问题,而我们没有去碰它:

Object.java.lang.RuntimeException.RuntimeException()@89F75B80AAD5A61ED1288B1136D17E39.cache.html:3144
Object.java.util.NoSuchElementException.NoSuchElementException()@89F75B80AAD5A61ED1288B1136D17E39.cache.html:3247
java.util.AbstractList$IteratorImpl.$next()@89F75B80AAD5A61ED1288B1136D17E39.cache.html:6218
com.google.gwt.user.client.ui.PopupPanel.$eventTargetsPartner()@89F75B80AAD5A61ED1288B1136D17E39.cache.html:7593
com.google.gwt.user.client.ui.PopupPanel.$previewNativeEvent()@89F75B80AAD5A61ED1288B1136D17E39.cache.html:8326

我打开了IteratorImpl:int i = 0,last = -1; 所以我不能将它设置为0,因为它已经被设置了。 - AKonst
在JavaScript中,该零最终出现在原型中。我建议您添加一个构造函数,在对象初始化时将其设置为0。也就是说,在类中添加public IteratorImpl() { i=0; }。我不确定它是否有帮助,但它确实在过去解决了类似火狐浏览器问题。我们计划在下一个发布版本之前再试一下。 - Steve
昨天,我向他们提交了一个bug:http://code.google.com/p/chromium/issues/detail?id=297570&thanks=297570&ts=1380027626 并且我替换了gwt-user中的Gwt AbstractList模拟类。由于使用Maven,这是一个非常大的hack,但它可以工作。 - AKonst
我不使用Maven,但是对于emul stuff的补丁,我保留了自己的“超级”目录树,并将其放置在编译时类路径中gwt-user.jar之前。这样我就可以保持GWT jars的原始状态。 - Steve

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接