我想知道是否有人能够可靠地在Eclipse中使用Groovy hot replace。我找不到任何有用的信息,所以我不确定它是否只是为其他人工作?或者没有人使用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中运行我的webapp时得到非常相似的结果,修改该行后也有相同的异常。重新启动junit,或者TomCat使新行正常工作,因此它绝对是一个热门替换问题。
那么我做错了什么?任何建议将不胜感激。
答案 0 :(得分:1)
我过去使用eclipse插件在web开发环境with groovy successfully中使用了热部署。
IIRC,我使用了groovyReset.jar,DCEVM和jdk1.7。
groovyReset.jar应该在类路径中并设置为java agent。我使用了groovy-eclipse插件文件夹中的一个(如eclipse/plugins/org.codehaus.groovy_2.3.7.xx-201411061335-e44-RELEASE/extras/groovyReset.jar
)
-javaagent:/groovyReset.jar
无需重新部署即可立即看到新的闭包和方法。当然,在一个方法中也包含一个简单的LOC。有时我需要重新启动虚拟机,但仍然呼吸新鲜空气。
在你的情况下,我认为至少groovyReset.jar必须存在。它负责重置元类。如果您反编译一个groovy类,您可以使用java.lang.Method
数组检查反射调用的方法调用。在热代码交换时,此阵列出现故障,需要重置。
答案 1 :(得分:0)
我已经在Eclipse中添加了Groovy插件,并为项目添加了groovy nature。正确的雄心勃勃的Java代码(泛型容器)突然出现奇怪的错误消息(错误和不合逻辑)
Groovy自然项目过度,在运行时使用Groovy的小片段编写脚本而不是更改java字符。 删除groovy功能不会阻止这些奇怪的消息。
我有机会,新电脑,新版Eclipse Mars,每年一次从头开始