1

jboss 7.1.3 にデプロイし、テストに arquillian を使用するプロジェクトがあり、それにコード カバレッジ メトリックを追加しようとしています。

管理されたコンテナオプション(jboss-as-arquillian-container-managed)を使用していますが、今のところ、arquillianがjbossを開始するために使用するjvm引数に-javaagentパラメータを追加しようとしたので、arquillian.xmlは次のようになります:

<?xml version="1.0" encoding="UTF-8"?>
<arquillian xmlns="http://jboss.org/schema/arquillian"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
    <defaultProtocol type="Servlet 3.0"/>

    <engine>
        <property name="deploymentExportPath">/tmp</property>
    </engine>

    <container qualifier="jboss"  default="true">
        <configuration>
            <property name="outputToConsole">true</property>
            <property name="jbossHome">[jboss home]</property>
            <property name="javaHome">[java home]</property>
            <property name="javaVmArguments">-Xmx2048m -XX:MaxPermSize=256m -XX:+HeapDumpOnOutOfMemoryError -Djboss.server.log.dir=logs -javaagent:[profile]\.m2\repository\org\jacoco\org.jacoco.agent\0.6.2.201302030002\org.jacoco.agent-0.6.2.201302030002-runtime.jar=destfile=C:\jacoco.exec,includes=*,excludes=,append=true,output=file,classdumpdir=classdumpdir,dumponexit=true</property>
            <property name="startupTimeoutInSeconds">120</property>
            <property name="allowConnectingToRunningServer">true</property>
        </configuration>
    </container>
</arquillian>

jacoco.exec ファイルと classdumpdir の両方が作成されているため、この引数が取得されていることは 100% 確実です。

問題は、jacoco.exec ファイルが空であることです。jboss が開始され、テストが実行されて正常に完了し、jboss がシャットダウンされ、classdumpdir が作成されます (したがって、jacoco の仕様によれば、これはクラスが適切に検出されることを意味します) が、jacoco.exec は完全に空のままです。

javaagent手動で開始したのとまったく同じ jboss に正確な保存引数を指定すると、すべて正常に動作します。

私は何を間違っていますか?

4

1 に答える 1

1

わかりました、問題は、jacocoがjvmがシャットダウンしたときにのみファイルの内容をダンプし(フックを登録します)、明らかにarquillian(少なくとも使用しているバージョン?)がjvmをうまくシャットダウンしないことでした。

テストクラスに次のメソッドを追加することになりました。

@After
public void writeOutJacocoData() {
    try {
        Class rtClass = Thread.currentThread().getContextClassLoader().getParent().loadClass("org.jacoco.agent.rt.RT");
        Object jacocoAgent = rtClass.getMethod("getAgent", null).invoke(null);
        Method dumpMethod = jacocoAgent.getClass().getMethod("dump", boolean.class);
        dumpMethod.invoke(jacocoAgent, false);
    } catch(ClassNotFoundException e) {
        logger.debug("no jacoco agent attached to this jvm");
    } catch (Exception e) {
        logger.error("while trying to dump jacoco data",e);
    }
}

その醜くて野蛮な(そして、公開されているjacocoアーティファクトで公開されていないjacocoクラスを使用しているため、リフレクションが機能します)が機能します。

于 2013-07-29T15:07:18.320 に答える