6

一部のクラスに対してバイトコードの変更を行うために使用されるJavaエージェントを作成していますorg.eclipse.jdt.core.JDTCompilerAdapterが、その1つです。javassit を使用して のexecute()メソッドをいくつか変更していorg.eclipse.jdt.core.JDTCompilerAdapterます。だから私はエージェントプロジェクトのようにecjを含めました(gradleを使用)

compile group: 'org.eclipse.jdt.core.compiler' ,name: 'ecj', version :'4.3.1'

ecj のいくつかのクラスを使用する必要があるためです。

エージェントの目的は、execute メソッドの呼び出しをインターセプトし、execute メソッドを変更して、いくつかの処理をトリガーする目的で、いくつかのクラスにいくつかの呼び出しを追加することです。

2 つのクラスを持つ単純な Java プロジェクトに対してエージェントをテストしています。プロジェクトは ant でビルドJDTCompilerAdapterされ、コンパイラとして使用されます。

ここにbuild.xmlファイルがあります

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project basedir="." default="build" name="TestProject">
<property file="build.properties" />

<property name="debuglevel" value="source,lines,vars"/>
<property name="target" value="1.7"/>
<property name="source" value="1.7"/>
<path id="PClasspath">
    <pathelement location="bin"/>
</path>


<target name="init">
    <mkdir dir="bin"/>
    <copy includeemptydirs="false" todir="bin">
        <fileset dir="src">
            <exclude name="**/*.java"/>
        </fileset>
    </copy>
</target>
<target name="clean">
    <delete dir="bin"/>
</target>
<target depends="clean" name="cleanall"/>
<target depends="init" name="build">

    <javac debug="true" debuglevel="${debuglevel}" destdir="bin" includeantruntime="false" source="${source}" target="${target}">
        <src path="src"/>
        <classpath refid="PClasspath"/>

    </javac>
</target>
<!--
<target description="copy Eclipse compiler jars to ant lib directory" name="init-eclipse-compiler">
    <copy todir="${ant.library.dir}">
        <fileset dir="${ECLIPSE_JDT_CORE}" includes="*.jar"/>
    </copy>
</target>-->
<target  name="build-e" >

    <property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/>
    <antcall target="build"/>
</target>

エージェントは、プロジェクトのビルド時に使用されます。したがって、エージェントをテストするには、次のコマンドを使用します。

java -jar agent-wrapper.jar --outdir ./out --exec ./build_wrapper.sh

build_wrapper.sh にはこれが含まれています( ecj 依存関係を追加したので、 bulid.xml にあるようにプロジェクトをコンパイルできJDTCompilerAdapterました <property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/>

../ant/bin/ant -lib ../eclipse/plugins/ecj-4.3.1.jar  build-e

アイデアは、エージェントラッパーが引数を解析することです (outdir はいくつかのものを生成するために使用され、exec は私のテストプロジェクトのビルドを起動するために使用されるスクリプトです) から実行されるコマンドを取得しますbuild_wrapper.sh(この場合は ../ant/bin/ant -lib ../eclipse/plugins/ecj-4.3.1.jar build-e) と追加コマンドに対する Java エージェントとして機能します。

この問題は、エージェントの実行中に発生します。出力は次のとおりです。

    java -jar  custom-agent.jar --outdir ./out --exec ./build_wrapper.sh                              [10:18:53]
Picked up JAVA_TOOL_OPTIONS: -javaagent:/Users/dev/TestAgent/project/custom-agent.jar=OUTDIR=/Users/dev/TestAgent/project/./out 
objc[30474]: Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/bin/java and /Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/libinstrument.dylib. One of the two will be used. Which one is undefined.
Buildfile: /Users/dev/TestAgent/project/build.xml

build-e:

init:
    [mkdir] Created dir: /Users/dev/TestAgent/project/bin

build:

BUILD FAILED
/Users/dev/TestAgent/project/build.xml:47: The following error occurred while executing this line:
/Users/dev/TestAgent/project/build.xml:32: Class org.eclipse.jdt.core.JDTCompilerAdapter could not be loaded because of an invalid dependency.

Total time: 2 seconds
abnormal termination, exit code: 1

エージェント プロジェクト内で ecj-4.3.1.jar を使用しない場合、ビルドは正常に実行されますexecute()。メソッドの呼び出しをインターセプトしますが、ecj jar の他のクラスを使用できません。

4

1 に答える 1

2

ショー ストッパー エラーは、「依存関係が無効なため、クラス org.eclipse.jdt.core.JDTCompilerAdapter をロードできませんでした」です。

このリンクhttp://help.eclipse.org/mars/index.jsp?topic=%2Forg.eclipse.jdt.doc.user%2Ftasks%2Ftask-ant_javac_adapter.htmを読むと、障害の最初のヒントが見つかる場合があります。

2 番目のヒントは、JDTCompilerAdapter の実行に必要な jar の 1 つが欠落している可能性があります。

JDTCompilerAdapter を機能させるために、JDTCompilerAdapter.jar と org.eclipse.jdt.core.jar の両方を ant/lib フォルダーにコピーしました。

上記のリンクに記載されているEclipseのバージョンとJavaのバージョンに基づく違いがあります。

于 2015-11-18T17:03:10.663 に答える