いくつかのクラスにいくつかのバイトコード変更を行うために使用されるJavaエージェントを作成していますorg.eclipse.jdt.core.JDTCompilerAdapter
がその1つです。私はメソッドの一部を変更するためにjavassitを使ってorg.eclipse.jdt.core.JDTCompilerAdapter
を使用しています。私はECJからいくつかのクラスを使用する必要があるように私は(のGradleを使用して)私のエージェントプロジェクトクラスorg.eclipse.jdt.core.JDTCompilerAdapterが無効な依存関係のためロードできませんでした
compile group: 'org.eclipse.jdt.core.compiler' ,name: 'ecj', version :'4.3.1'
のようにECJが含まれています。
エージェントの目的は、executeメソッドを変更していくつかの呼び出しをいくつかのクラスに追加して処理をトリガーすることです。
2つのクラスを持つSimple 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は、私がbulid.xml <property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/>
に持っているとして、私はJDTCompilerAdapter
でプロジェクトをコンパイルすることができるように、私はECJの依存関係を追加した(これが含まれています
../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エージェントとして自己にコマンドに追加します。
この問題は、エージェントの実行中に発生します。ここでは、出力は次のようになります。私は私のエージェントのプロジェクト内ECJ-4.3.1.jarを使用しない場合は、ビルドはうまく動作します
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 jarから。
このリンクが役立つかどうかを確認してください。そのリンクごとに、クラスパスの競合が存在する可能性があります。 https://www.liferay.com/community/forums/-/message_boards/message/43851128 – Rao