我们有一些Groovy的遗留代码,我们想从应用程序中删除Groovy,因此,我们需要获取使用gmaven插件后生成的java源代码。
基本上,换句话说,我正在动态生成新类(使用gmaven Groovy maven插件),我希望能够获得这些生成类的java源代码。
我研究了一下,可以看出这个插件的唯一目标是
<goal>generateStubs</goal>
<goal>compile</goal>
<goal>generateTestStubs</goal>
<goal>testCompile</goal>
我无法看到任何允许您获取完全实现的java源代码的目标,存根代码对我们来说还不够,因为我们需要最终的实现源代码才能摆脱Groovy。
答案 0 :(得分:4)
我对gmaven插件不太熟悉,但我认为它将groovy代码编译成字节代码。在这种情况下,您可以使用字节码反编译器,有一个很好的列表here。在过去,我使用过JAD,这非常好。最好的还会尝试根据类名创建有意义的变量名。
虽然有一个警告 - Groovy对象是从GObject派生的,而不是java.lang.Object,所以你可能需要保留groovy jar,直到完成groovy-&gt; java移植。另外,要做好准备,不会很容易阅读java ...
答案 1 :(得分:2)
它可能超出了您的范围(1岁),但我遇到了同样的问题,并找到了一种从反编译的groovy类中检索算法(而不是java源代码)的方法。
您可能需要查看:http://michael.laffargue.fr/blog/2013/11/02/decompiling-groovy-made-classes/
答案 2 :(得分:1)
生成的存根对您没用。他们就是他们的名字所暗示的:存根。
存根仅在进行联合java / groovy编译时有用。那是因为java / groovy混合项目中涉及两个编译器。
groovy代码将使用groovyc
编译器进行编译,结果是字节代码。
这是生成存根的示例:
package maba.groovy;
import java.lang.*;
import java.io.*;
import java.net.*;
import java.util.*;
import groovy.lang.*;
import groovy.util.*;
@groovy.util.logging.Log4j() public class Order
extends java.lang.Object implements
groovy.lang.GroovyObject {
public groovy.lang.MetaClass getMetaClass() { return (groovy.lang.MetaClass)null;}
public void setMetaClass(groovy.lang.MetaClass mc) { }
public java.lang.Object invokeMethod(java.lang.String method, java.lang.Object arguments) { return null;}
public java.lang.Object getProperty(java.lang.String property) { return null;}
public void setProperty(java.lang.String property, java.lang.Object value) { }
public int getPrice() { return (int)0;}
public void setPrice(int value) { }
public int getQuantity() { return (int)0;}
public void setQuantity(int value) { }
@java.lang.Override() public java.lang.String toString() { return (java.lang.String)null;}
}
正如您所看到的,没有任何用处。你仍然会依赖一些时髦的库。
答案 3 :(得分:1)
这个问题已经发布在邮件清单上了[0]。总结一下:Groovy到Java很难实现,因为Java中没有语言结构和API(如果你想完全删除Groovy依赖)。
特别是通过引入调用站点缓存和其他性能优化技术,生成的Java代码看起来很像这样(为了简单起见,我只是将一些脚本放到JD-GUI [1]中):
public class script1351632333660 extends Script
{
public script1351632333660()
{
script1351632333660 this;
CallSite[] arrayOfCallSite = $getCallSiteArray();
}
public script1351632333660(Binding arg1)
{
Binding context;
CallSite[] arrayOfCallSite = $getCallSiteArray();
ScriptBytecodeAdapter.invokeMethodOnSuperN($get$$class$groovy$lang$Script(), this, "setBinding", new Object[] { context });
}
public Object run()
{
CallSite[] arrayOfCallSite = $getCallSiteArray(); Object items = ScriptBytecodeAdapter.createList(new Object[0]);
Object[] item = (Object[])ScriptBytecodeAdapter.castToType(ScriptBytecodeAdapter.createList(new Object[] { "Fluff", arrayOfCallSite[1].callConstructor($get$$class$java$util$Date()), (Integer)DefaultTypeTransformation.box(11235813) }), $get$array$$class$java$lang$Object());
arrayOfCallSite[2].call(items, item);
arrayOfCallSite[3].callCurrent(this, items);
ValueRecorder localValueRecorder = new ValueRecorder();
try
{
Object tmp102_101 = items; localValueRecorder.record(tmp102_101, 8);
Object tmp126_121 = arrayOfCallSite[4].call(tmp102_101, new script1351632333660._run_closure1(this)); localValueRecorder.record(tmp126_121, 14); if (DefaultTypeTransformation.booleanUnbox(tmp126_121)) localValueRecorder.clear(); else ScriptBytecodeAdapter.assertFailed(AssertionRenderer.render("assert items.findAll { it }", localValueRecorder), null); } finally {
localValueRecorder.clear(); throw finally; } return null; return null; }
static { __$swapInit();
Long localLong1 = (Long)DefaultTypeTransformation.box(0L);
__timeStamp__239_neverHappen1351632333665 = localLong1.longValue();
Long localLong2 = (Long)DefaultTypeTransformation.box(1351632333665L);
__timeStamp = localLong2.longValue(); }
class _run_closure1 extends Closure implements GeneratedClosure { public _run_closure1(Object _thisObject) { super(_thisObject); }
public Object doCall(Object it) { CallSite[] arrayOfCallSite = $getCallSiteArray(); return it; return null;
}
// ...
[0] http://groovy.329449.n5.nabble.com/Java-lt-gt-Groovy-converters-td337442.html