Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Class org.eclipse.jdt.core.JDTCompilerAdapter could not be loaded because of an invalid dependency

I am creating a java agent that will be used to to do some bytecode modification to some classes org.eclipse.jdt.core.JDTCompilerAdapter is one of them. I am using javassit to modify some the execute() method of org.eclipse.jdt.core.JDTCompilerAdapter. So I have included ecj as in my agent project (using gradle)

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

As I need to use some classes from ecj.

The goal of the agent is to intercept the calls to execute method, modify the execute method to add some calls to some of my classes in the aim of triggering some processing.

I am testing the agent against a Simple java project with 2 classes. the project is builded with ant and uses JDTCompilerAdapter as a compiler.

Here is the build.xml file

<?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>

The agent is to be used when building a project. So for testing the agent I use this command:

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

build_wrapper.sh contains this (I have added ecj dependency so I could compile the project with JDTCompilerAdapter as I have in bulid.xml <property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/> :

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

The idea is that the agent-wrapper will parse the argument (outdir is used to generate some stuff and exec is a script used to launch a the build of my test project) get the command to be executed from build_wrapper.sh (in this case ../ant/bin/ant -lib ../eclipse/plugins/ecj-4.3.1.jar build-e) and add it self as java agent to the command.

The problem occurs during the execution of the agent. Here is the output:

    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

When I don't use ecj-4.3.1.jar inside my agent project, the build runs well I intercept the call to execute() method but I can't use the other classes from ecj jar.

like image 802
Master Mind Avatar asked Nov 08 '15 21:11

Master Mind


1 Answers

The show stopper error is "Class org.eclipse.jdt.core.JDTCompilerAdapter could not be loaded because of an invalid dependency."

First hint at the fault might be found from reading this link http://help.eclipse.org/mars/index.jsp?topic=%2Forg.eclipse.jdt.doc.user%2Ftasks%2Ftask-ant_javac_adapter.htm

The second hint might be that one of the jars required for running the JDTCompilerAdapter is missing.

To get the JDTCompilerAdapter to work I copied both the JDTCompilerAdapter.jar and org.eclipse.jdt.core.jar into the ant/lib folder.

There are differences based on version of eclipse and the version of java which are documented in the link mentioned above.

like image 122
Mike Murphy Avatar answered Nov 04 '22 04:11

Mike Murphy