2015-11-08 19 views
6

Ich erstelle einen Java-Agenten, mit dem einige Bytecode-Änderungen an einigen Klassen vorgenommen werden. org.eclipse.jdt.core.JDTCompilerAdapter ist einer davon. Ich verwende javassit, um einige der execute() Methode von org.eclipse.jdt.core.JDTCompilerAdapter zu ändern. So habe ich eingeschlossen ecj wie in meinem Agenten Projekt (mit gradle)Klasse org.eclipse.jdt.core.JDTCompilerAdapter konnte wegen einer ungültigen Abhängigkeit nicht geladen werden

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

Wie ich aus ecj einige Klassen verwenden müssen.

Das Ziel des Agenten ist es, die Aufrufe zur Ausführung der Methode abzufangen, die Methode execute zu modifizieren, um einige meiner Klassen in einige Aufrufe einzufügen, um eine Verarbeitung auszulösen.

Ich teste den Agenten gegen ein einfaches Java-Projekt mit 2 Klassen. Das Projekt ist mit Ant gebaut und verwendet JDTCompilerAdapter als Compiler. Hier

ist die Datei 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> 

Der Agent verwendet werden soll, wenn ein Projekt zu bauen. Also das Mittel zum Testen verwende ich diesen Befehl ein:

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

build_wrapper.sh diese enthält (Ich habe ecj Abhängigkeit hinzugefügt, so konnte ich das Projekt mit JDTCompilerAdapter kompilieren, wie ich in bulid.xml haben <property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/>:

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

Die Idee ist, dass der Agent-Wrapper das Argument analysieren wird (outdir wird verwendet, um einige Sachen zu generieren und exec ist ein Skript, um den Build meines Testprojekts zu starten) den Befehl aus build_wrapper.sh (in diesem case ../ant/bin/ant -lib ../eclipse/plugins/ecj-4.3.1.jar build-e) und fügen Sie es selbst als Java-Agent zum Befehl hinzu.

Das Problem tritt während der Ausführung des Agenten auf. Hier ist die Ausgabe:

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 

Wenn ich nicht ecj-4.3.1.jar in meinem Agenten Projekt verwenden, das Build läuft gut abfangen ich den Anruf zu execute() Methode, aber ich kann nicht die anderen Klassen verwenden aus ecj jar.

+0

Bitte schauen Sie, ob dieser Link hilft. Gemäß diesem Link könnte es einen Klassenpfadkonflikt geben. https://www.liveray.com/community/forums/-/message_boards/message/43851128 – Rao

Antwort

2

Der show stopper Fehler ist "Klasse org.eclipse.jdt.core.JDTCompilerAdapter konnte wegen einer ungültigen Abhängigkeit nicht geladen werden."

Erster Hinweis auf die Fehler könnte aus der Lektüre dieses Link http://help.eclipse.org/mars/index.jsp?topic=%2Forg.eclipse.jdt.doc.user%2Ftasks%2Ftask-ant_javac_adapter.htm

Der zweite Hinweis, dass eines der Gläser für den Betrieb des JDTCompilerAdapter erforderlich sein könnte gefunden werden, fehlt.

Um den JDTCompilerAdapter zum Laufen zu bringen, habe ich sowohl JDTCompilerAdapter.jar als auch org.eclipse.jdt.core.jar in den ant/lib-Ordner kopiert.

Es gibt Unterschiede basierend auf der Version von Eclipse und der Version von Java, die in dem oben genannten Link dokumentiert sind.

Verwandte Themen