2017-06-30 10 views
1

nar-maven-pluginを使用してMavenでJNIプロジェクトを設定しました。 JavaコードとC++コードの両方がプロジェクトに存在します。メインコードは明らかに正しくコンパイルされます(C++とJavaの両方)。問題はテストコード(JUnit)にあります。JUnitテストのネイティブコードが `nar-maven-plugin`でコンパイルされていません

テストコードは、それ自体がネイティブメソッドを持つ1つのJavaクラスを定義しました。対応するネイティブコードは、ディレクトリに存在

<project root> 
+- src 
    +- test 
     +- c++ 

あり、このネイティブテストコードは、これまでにコンパイルされていることをビルドメッセージからの証拠はありませんし、私はコマンドラインからnmを実行すると、対応するネイティブメソッドがまったく表示されません。ビルドプロセスによって作成されたDLL。また、私は意図的にテストコードに構文エラーを入れ、コンパイル時にエラーが発生するかどうかを再コンパイルします。コードは決してコンパイルされないという私の信念と一致して、エラーはありません。

これに対応して、mvn installの間にテストを実行するとUnsatisfiedLinkErrorとなります。テストが失敗した時点から、メイン(非テスト)コードのネイティブメソッドが適切にロードされてリンクされていることがわかります。したがって、ネイティブテストコードの構築とリンクに関連する問題があると結論づけます。

私は現在、ネイティブコード用にEclipse IDEとMinGWコンパイラを使用しています。私のPOMの

関連するセクションは以下の通りです(少し早い設定の問題に関連しAvoiding machine-dependent POM with MinGW compiler and nar-maven-pluginに私の答えから更新):

<profiles> 
    <profile> 
     <id>Windows-MinGW</id> 
     <activation> 
      <os> 
       <family>Windows</family> 
      </os> 
     </activation> 
     <build> 
      <plugins> 
       <plugin> 
        <groupId>com.github.maven-nar</groupId> 
        <artifactId>nar-maven-plugin</artifactId> 
        <version>3.5.1</version> 
        <extensions>true</extensions> 
        <configuration> 
         <cpp> 
          <options> 
            <option>-std=c++1y</option> 
          </options> 
         </cpp> 

         <linker> 
          <name>g++</name> 
          <options> 
           <option>-Wl,--kill-at</option> 
          </options> 
         </linker> 
        </configuration> 
       </plugin> 
      </plugins> 
     </build> 
    </profile> 
</profiles> 

<build> 
    <defaultGoal>integration-test</defaultGoal> 

    <plugins> 
     <plugin> 
      <groupId>com.github.maven-nar</groupId> 
      <artifactId>nar-maven-plugin</artifactId> 
      <version>3.5.1</version> 
      <extensions>true</extensions> 
      <configuration> 
       <cpp> 
        <defines> 
         <define>EXPORT_DLL</define> 
        </defines> 
       </cpp> 
       <libraries> 
        <library> 
         <type>jni</type> 
         <narSystemPackage>com.mycompany.sandbox</narSystemPackage> 
        </library> 
       </libraries> 
      </configuration> 
     </plugin> 
    </plugins> 

</build> 

この問題を処理するための既知の方法はありますか? (たぶん付加的な構成タグですか?)

答えて

1

私はこれをうまく利用しましたが、それほど美味しくありませんでした。私は最後にPOM部品をあげる、しかし、アウトラインでは、これらの手順は次のとおりです。メインのコードをコンパイルするための質問のようにプロジェクトを設定し

  • nar-maven-pluginへの<tests>セクションを使用しますDLL/SOバックアップJavaテストを作成しないようにネイティブテストの実行ファイルを作成するように実際に設定されていることに注意してください。
  • <testOptions>をリンカーに指定して実行可能ファイルの代わりにDLL/
  • <testOptions>をさらに指定して、テストコードをメインプロジェクトコードとリンクさせるあなたはjni(というよりもsharedまたはstatic)ライブラリの種類を選択すると、これは自動的にサポートされていないため
  • 試験前のパスにテストライブラリはと

が、よりに最後の弾丸を拡張した後、それを削除

  • 移動詳細:コンパイルするテストコードを取得しても、テストディレクトリがテスト実行時にjava.library.pathにないため、Javaからロードすることはできません。私が見つけることができる最高の解決策は、パス上のディレクトリに一時的にテストライブラリを移動することでした。これは、簡単に利用できる設定オプションのためにパスを変更するよりも簡単だったようです。パス上にライブラリがある場合は、JUnitテストの実行中にいつものようにSystem.loadLibraryを使用できます。

    ここでは、上記を実現する拡張POMセグメントを示します。これは私が質問にあったものに基づいていますが、新しい部分では答えの冒頭で弾丸を達成する必要があります。テストをサポートするJNIコードはTestWrapper.cppのファイル/src/test/c++にあることに注意してください。 (私はそれがJNIソースファイルの標準的な命名規則ではありません知っている。)

    :私だけprofilesセクションに代表される私のWindows 10マシン上でテスト用のリンカのフラグを出してきました。この時点で。同様に、コピー/削除は明示的に.dllの拡張子を持ちます。これは調整する必要があります。ただし、.dllファイルを取得しても、プラグインが作成すると、拡張子は.exeになります!)この時点で、私のPOMは他のマシン/アーキテクチャでは壊れていませんが、それらをここから作業させるので、そのまま答えを投稿する価値があるようです。

    <profiles> 
        <profile> 
         <id>Windows-MinGW</id> 
         <activation> 
          <os> 
           <family>Windows</family> 
          </os> 
         </activation> 
         <build> 
          <plugins> 
           <plugin> 
            <groupId>com.github.maven-nar</groupId> 
            <artifactId>nar-maven-plugin</artifactId> 
            <version>3.5.1</version> 
            <extensions>true</extensions> 
            <configuration> 
             <cpp> 
              <options> 
               <option>-std=c++1y</option> 
              </options> 
             </cpp> 
             <linker> 
              <name>g++</name> 
              <options> 
               <option>-Wl,--kill-at</option> 
              </options> 
              <testOptions> 
               <!-- Put the -shared flag onto the linker - That will force a DLL instead of an EXE --> 
               <testOption>-shared</testOption> 
               <!-- We cannot easily link to the *library* that was created for the main project but we can get the compiled object files with the following option --> 
               <testOption>${project.build.directory}/nar/obj/${nar.aol}/*.o</testOption> 
              </testOptions> 
             </linker> 
            </configuration> 
           </plugin>     
          </plugins> 
         </build> 
        </profile> 
    </profiles> 
    
    <build> 
        <defaultGoal>integration-test</defaultGoal> 
    
        <plugins> 
         <plugin> 
          <groupId>com.github.maven-nar</groupId> 
          <artifactId>nar-maven-plugin</artifactId> 
          <version>3.5.1</version> 
          <extensions>true</extensions> 
          <configuration> 
           <cpp> 
            <defines> 
             <define>EXPORT_DLL</define> 
            </defines> 
           </cpp> 
           <libraries> 
            <library> 
             <type>jni</type> 
             <narSystemPackage>com.mycompany.mypackage</narSystemPackage> 
            </library> 
           </libraries> 
           <tests> 
            <test> 
             <name>TestWrapper</name> 
             <run>false</run> 
            </test> 
           </tests> 
          </configuration> 
         </plugin> 
    
         <plugin> 
          <groupId>org.apache.maven.plugins</groupId> 
          <artifactId>maven-antrun-plugin</artifactId> 
          <version>1.7</version> 
          <executions> 
           <execution> 
            <id>copy-test-lib-to-path</id> 
            <phase>pre-integration-test</phase> 
            <configuration> 
             <target> 
              <copy file="${project.build.directory}/test-nar/bin/${nar.aol}/TestWrapper.exe" tofile="${project.build.directory}/nar/${project.artifactId}-${project.version}-${nar.aol}-jni/lib/${nar.aol}/jni/TestWrapper.dll"/> 
             </target> 
            </configuration> 
            <goals> 
             <goal>run</goal> 
            </goals> 
           </execution> 
           <execution> 
            <id>delete-test-lib-from-deployment</id> 
            <phase>post-integration-test</phase> 
            <configuration> 
             <target> 
              <delete file="${project.build.directory}/nar/${project.artifactId}-${project.version}-${nar.aol}-jni/lib/${nar.aol}/jni/TestWrapper.dll"/> 
             </target> 
            </configuration> 
            <goals> 
             <goal>run</goal> 
            </goals> 
           </execution> 
          </executions> 
         </plugin> 
    
        </plugins>