有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

如何获取Groovy生成的java源代码

Groovy中有一些遗留代码,我们希望从应用程序中删除Groovy,因此,我们需要获得使用gmaven插件后生成的java源代码

基本上,换句话说,我正在动态生成新类(使用gmaven Groovy maven插件),我希望能够获得生成的类的java源代码

我做了一些研究,发现这个插件的唯一目标是

<goal>generateStubs</goal>
<goal>compile</goal>
<goal>generateTestStubs</goal>
<goal>testCompile</goal>

我看不出有任何目标可以让您获得完全实现的java源代码,存根代码对我们来说是不够的,因为我们需要最终实现的源代码来摆脱Groovy


共 (4) 个答案

  1. # 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

    [1]http://java.decompiler.free.fr

  2. # 2 楼答案

    我不太熟悉gmaven插件,但我认为它可以将groovy代码编译成字节码。在本例中,您可以使用字节码反编译器,这里有一个很好的列表here。过去我用过JAD,它很不错。最好的也会尝试根据类名创建有意义的变量名

    不过有一个警告——Groovy对象是从GObject派生的,而不是java。因此,您可能需要将groovy jar保留到groovy->;java移植已经完成。另外,请准备好,它将不是一个非常容易阅读的java

  3. # 3 楼答案

    生成的存根将对您毫无用处。它们正是它们的名字所暗示的:存根

    存根仅在执行java/groovy联合编译时有用。这是因为java/groovy混合项目中涉及两个编译器

    1. 解析groovy
    2. 创建存根
    3. 编译java和存根(使用javac)
    4. 继续groovy编译(使用groovyc)

    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;}
    }
    

    正如你所看到的,没有什么有用的东西。您仍然需要依赖一些groovy库