Im Rahmen eines Projekts, bei dem Clojure zum Erstellen von Unit-Tests für eine vorhandene Java Legacy-Anwendung eingesetzt werden soll, stand ich kürzlich vor der Aufgabe, Clojure in den vorhandenen Ant-Build einzubauen.

Das zusätzlich eingebaute Target enthielt eine <java> Task, die prinzipiell folgenden Aufbau hatte:

<java classname="clojure.main"
    <classpath>
        <!-- ... -->
    </classpath>
    <arg value="-i"/>
    <arg value="tests/tests.clj"/>
</java>

Beim Aufrufen des Builds trat eine java.lang.NoClassDefFoundError Exception auf, deren Stack-Trace unter anderem die folgende Zeile enthielt:

[java] Caused by: java.lang.VerifyError: verification failed at PC 214
       in clojure.core.protocols$fn__5385:
       invoke((Ljava.lang.Object;Ljava.lang.Object;Ljava.lang.Object;)Ljava.lang.Object;):
       incompatible type on stack

“verification failed at PC 214″. “incompatible type on stack”. Huh?

Der direkte Aufruf von Clojure (also ohne Ant) mittels “java -cp … clojure.main” funktionierte auf diesem System problemlos.

Ein bisschen Zeit in Google ergab, dass es wohl manchmal Probleme mit dem Ausführen von Clojure unter OpenJDK gibt.

Ant ruft auf dem betreffenden System offenbar mittels der Umgebungsvariable $JAVA_HOME das “java” Binary unter /usr/lib64/jvm/java/jre/bin/java auf, hinter dem sich ein gij für die Java Version 1.5.0 verbirgt.

Die Lösung bestand darin, der <java> Task einen Parameter “jvm” mitzugeben, der auf das tatsächlich zu verwendende “java” Binary verweist. In diesem Fall genügte es, die Option jvm=”/usr/bin/java” hinzuzufügen, sodass dass eingefügte Target folgendermaßen lautete:

<target name="test" depends="">
    <java classname="clojure.main"
        jvm="/usr/bin/java"
        fork="true"
        failonerror="false">
        <classpath>
            <dirset dir="/opt/intrexx/tomcat/webapps/ibtest/WEB-INF/lib" />
            <dirset dir="/opt/intrexx/tomcat/webapps/ibtest/WEB-INF/classes" />
            <!-- ... (some more) -->
            <pathelement location="${deploy.home}/WEB-INF/lib/clojure.jar"/>
            <pathelement location="${deploy.home}/WEB-INF/lib/clojure-contrib.jar"/>
        </classpath>
        <arg value="-i"/>
        <arg value="tests/tests.clj"/>
    </java>
</target>

Verwendete Versionen:

Clojure 1.2.0
Apache Ant 1.7.1
java version “1.6.0_20″
OpenJDK Runtime Environment (IcedTea6 1.9.2) (suse-0.2.1-x86_64)
OpenJDK 64-Bit Server VM (build 17.0-b16, mixed mode)
gcj: 4.5 (gcc version 4.5.0 20100604 [gcc-4_5-branch revision 160292] (SUSE Linux))

Tags: , , ,

Comments are closed.