【发布时间】:2015-06-30 00:11:24
【问题描述】:
我想知道是否有人能够让 Groovy 热替换在 Eclipse 中可靠地工作。我找不到任何有用的信息,所以我不确定它是否是 b/c 它只是为其他人工作?还是没有人使用 Eclipse 进行 Groovy 开发?
我已经尝试使用最新的 Eclipse (4.5 Mars) 和最新的 Groovy-Eclipse 插件(来自http://dist.springsource.org/snapshot/GRECLIPSE/e4.5/ 的 Groovy Eclipse 2.9.2),但我仍然无法获得可靠的热替换。
一些简单的热替换方案可以正常工作。但是,稍微复杂一点就会导致奇怪的 Groovy 异常。我在不同的情况下会遇到不同的错误,但我能够在一个简单的 junit 中重现一个错误,所以我将使用一些简化的域对象来演示这个错误。
HotSwapTests.groovy:
class HotSwapTests {
@Test
public void testHotReplace() {
DefaultTxView transactionGroup = new DefaultTxView();
List<Default> defaults = [];
Default d1 = new Default(ProducerAccountTransactionType.REPAID_AMOUNT, ParticipantAccountType.DEFAULT);
Default d2 = new Default(ProducerAccountTransactionType.REPAID_AMOUNT, ParticipantAccountType.DEFAULT);
d1.setCancelledDefault(d2);
defaults << d1;
transactionGroup.setDefaultTransactions(defaults);
while (true) {
Default result = transactionGroup.getRepaymentTransaction();
println result
}
}
}
DefaultTxView.groovy:
public class DefaultTxView {
def List<Default> defaultTransactions;
public Default getRepaymentTransaction() { return getTransactionOfType(REPAID_AMOUNT); }
public Default getTransactionOfType(ProducerAccountTransactionType type) {
return defaultTransactions.find { it.getType() == type };
}
Default.java:
The contents of this domain object are not really important - it's a simple POJO.
现在,为了测试热插拔,我在标记的行放置了一个断点:
while (true) {
Default result = transactionGroup.getRepaymentTransaction(); <<< break
println result
}
然后我去DefaultTxView.groovy修改传入find方法的闭包里面的代码:
public Default getTransactionOfType(ProducerAccountTransactionType type) {
return defaultTransactions.find { it.getType() == type && it.getCancelledDefault() == null};
}
我在保存文件时没有收到任何警告或错误消息,但如果我现在尝试跨过修改的行,我会收到以下异常:
java.lang.ArrayIndexOutOfBoundsException: 2
at ca.gc.agr.app.web.jsf.producer.DefaultTxView$_getTransactionOfType_closure1.doCall(DefaultTxView.groovy:15)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:324)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:278)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1016)
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:39)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
at org.codehaus.groovy.runtime.callsite.BooleanReturningMethodInvoker.invoke(BooleanReturningMethodInvoker.java:48)
at org.codehaus.groovy.runtime.callsite.BooleanClosureWrapper.call(BooleanClosureWrapper.java:50)
at org.codehaus.groovy.runtime.DefaultGroovyMethods.find(DefaultGroovyMethods.java:3060)
at org.codehaus.groovy.runtime.dgm$175.invoke(Unknown Source)
at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoMetaMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:271)
at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:53)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at ca.gc.agr.app.web.jsf.producer.DefaultTxView.getTransactionOfType(DefaultTxView.groovy:15)
at ca.gc.agr.app.web.jsf.producer.DefaultTxView$getTransactionOfType$1.callCurrent(Unknown Source)
at ca.gc.agr.app.web.jsf.producer.DefaultTxView.getRepaymentTransaction(DefaultTxView.groovy:11)
at ca.gc.agr.app.web.jsf.producer.DefaultTxView$getRepaymentTransaction$0.call(Unknown Source)
at ca.gc.agr.app.web.jsf.temp.HotSwapTests.testHotReplace(HotSwapTests.groovy:29)
在 TomCat 中运行我的 web 应用程序时,我得到了非常相似的结果,修改该行后出现了同样的异常。重新启动junit,或者TomCat 使新线路工作正常,所以这绝对是一个热替换问题。
那么我做错了什么?任何建议将不胜感激。
【问题讨论】: