5

Groovy を使用したレガシー コードがいくつかあり、Groovy をアプリケーションから削除したいので、gmaven プラグインを使用した後に生成された Java ソース コードを取得する必要があります。

基本的に、言い換えれば、新しいクラスを動的に生成しています (gmaven Groovy maven プラグインを使用)。そのような生成されたクラスの Java ソース コードを取得できるようにしたいと考えています。

少し調べてみたところ、このプラグインの唯一の目標は

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

完全に実装された Java ソース コードを取得できるようにする目標が見えません。Groovy を取り除くには、最終的な実装ソース コードが必要なので、スタブ コードでは十分ではありません。

4

4 に答える 4

4

私は gmaven プラグインにあまり詳しくありませんが、Groovy コードをバイトコードにコンパイルすると思います。この場合、バイトコード逆コンパイラを使用できます。ここに素敵なリストがあります。過去にJADを使ったことがありますが、とても良かったです。最良のものは、クラス名に基づいて意味のある変数名を作成しようとします。

ただし、Groovy オブジェクトは java.lang.Object ではなく GObject から派生しているため、groovy->java への移植が完了するまで Groovy jar を保持する必要があります。また、非常に読みやすいJavaではないことに注意してください...

于 2012-10-31T07:35:43.853 に答える
2

それはあなたの範囲外かもしれませんが(1歳)、同じ問題と戦い、逆コンパイルされたgroovyクラスからアルゴリズム(Javaソースコードではない)を取得する方法を見つけました.

ご覧になることをお勧めします: http://michael.laffargue.fr/blog/2013/11/02/decompiling-groovy-made-classes/

于 2013-11-19T08:33:05.480 に答える
1

生成されたスタブは役に立ちません。それらは、その名前が示すとおり、スタブです。

スタブは、Java/Groovy の共同コンパイルを行う場合にのみ役立ちます。これは、Java/Groovy 混合プロジェクトに 2 つのコンパイラーが関与しているためです。

  1. グルーヴィーな構文解析
  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;}
}

ご覧のとおり、有用なものは何もありません。そして、いくつかのグルーヴィーなライブラリーに依存することになります。

于 2012-10-31T07:47:49.197 に答える
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

于 2012-10-31T09:26:28.413 に答える