How to get Groovy generated Java source code

We have the code for legacy code with Groovy, and we want to remove it from the Groovy application, so we need to get the java source code generated after using the gmaven plugin.

Basically, I dynamically generate new classes (using the gmaven Groovy maven plug in), and I would like to get java source code for such generated classes.

I have studied a little and see that the only goals of this plugin are

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

I don’t see a goal that allows you to get fully implemented Java source code; stub code is not enough for us, because we need the final implementation source code to get rid of Groovy.

+4
source share
4 answers

I am not very familiar with the gmaven plugin, but I assume that it compiles groovy code into byte code. In this case, you can use the bytecode decompiler, there is a good list here . I used to use JAD, and it was nice. The best ones will also try to create meaningful variable names based on class names.

One warning is that groovy objects are derived from GObject, not java.lang.Object, so you probably need to save the groovy jar until porting groovy -> java. Also, be prepared that it will not be very easy to read java ...

+4
source

It may not be within your scope (1 year), but I struggled with the same problem and found a method to extract the algorithm (not the java source code) from the decompiled groovy classes.

You can look at: http://michael.laffargue.fr/blog/2013/11/02/decompiling-groovy-made-classes/

+2
source

The generated stubs will be useless to you. This is exactly what their names suggest: cigarette butts.

Pins are only useful when jointly compiling java / groovy. This is because there are two compilers involved in the java / groovy mixed project.

  • Parsing groovy
  • Create Stubs
  • Compile java and stubs (using javac)
  • Continue groovy compilation (using groovyc)

The groovy code will be compiled using the groovyc compiler, and the result will be bytecode.

This is an example of a generated stub:

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

As you can see, there is nothing useful. And you will still depend on some groovy libraries.

+1
source

This question was on the mailing list some time ago [0]. To summarize: Groovy for Java is hard to achieve since there are language constructs and APIs (if you want to completely remove the Groovy dependency) that are not available in Java.

In particular, with the introduction of site caching and other performance optimization methods, the generated Java code will be very similar to this question (for simplicity, I just threw a few script into the 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

+1
source

Source: https://habr.com/ru/post/1443160/


All Articles