2016-08-25 17 views
2

Mavenを使用してLWJGLプロジェクトをセットアップしようとしています。私はthe official websiteから "始動する"ソースコードの例を使用しています。 、(当然のMavenを使用してプロジェクトを構築した後)MavenにLWJGLインストールのマニフェスト属性が含まれていない

System.out.println("Hello LWJGL " + Version.getVersion() + "!"); 

これは、Eclipse環境でも問題なく動作します:

は、これは単純なバージョンチェックなどLWJGLのマニフェスト属性を、アクセス数行を含みclean installを実行して、CMDを通じて**-jar-with-dependencies.jarを実行しているときには、次の例外がスローさの取得

java.lang.NullPointerException 
     at org.lwjgl.system.APIUtil.apiGetManifestValue(APIUtil.java:97) 
     at org.lwjgl.Version.getVersion(Version.java:33) 
     at HelloWorld.run(HelloWorld.java:43) 
     at HelloWorld.main(HelloWorld.java:130) 

これはのためでありますAPIUtilによって作成されたオブジェクトには、という属性は含まれていませんが、Mavenによって作成されたバージョンのみです。

これはなぜですか?私のpom.xmlはバグですか?そうでないとLWJGL 3.0.0ですか?

は、これが私のpom.xml次のとおりです。

<properties> 
    <mainClass>HelloWorld</mainClass> 
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
    <finalName>${project.artifactId}-${project.version}.jar</finalName> 
</properties> 

<dependencies> 
    <dependency> 
     <groupId>org.lwjgl</groupId> 
     <artifactId>lwjgl</artifactId> 
     <version>3.0.0</version> 
    </dependency> 
    <dependency> 
     <groupId>org.lwjgl</groupId> 
     <artifactId>lwjgl-platform</artifactId> 
     <version>3.0.0</version> 
     <classifier>natives-windows</classifier> 
    </dependency> 
    <dependency> 
     <groupId>org.lwjgl</groupId> 
     <artifactId>lwjgl-platform</artifactId> 
     <version>3.0.0</version> 
     <classifier>natives-linux</classifier> 
    </dependency> 
    <dependency> 
     <groupId>org.lwjgl</groupId> 
     <artifactId>lwjgl-platform</artifactId> 
     <version>3.0.0</version> 
     <classifier>natives-osx</classifier> 
    </dependency> 
</dependencies> 

<build> 
    <plugins> 
     <plugin> 
      <groupId>org.apache.maven.plugins</groupId> 
      <artifactId>maven-compiler-plugin</artifactId> 
      <version>3.5.1</version> 
      <configuration> 
       <source>1.8</source> 
       <target>1.8</target> 
      </configuration> 
     </plugin> 
     <plugin> 
      <groupId>org.apache.maven.plugins</groupId> 
      <artifactId>maven-assembly-plugin</artifactId> 
      <executions> 
       <execution> 
        <phase>package</phase> 
        <goals> 
         <goal>single</goal> 
        </goals> 
       </execution> 
      </executions> 
      <configuration> 
       <descriptorRefs> 
        <descriptorRef>jar-with-dependencies</descriptorRef> 
       </descriptorRefs> 
       <archive> 
        <manifest> 
         <mainClass>${mainClass}</mainClass> 
        </manifest> 
       </archive> 
      </configuration> 
     </plugin> 
    </plugins> 
</build> 

答えて

2

LWJGL 3.0.0 is looking inside the Manifest a property called "Implementation-Version"が、あなたはユーバー-jarファイルを作ったときので、このエラーが起こり、このプロパティは設定されませんでした。

これは本当にあなたがユーバー-jarファイルを作った方法の問題ではありません:あなたはjar-with-dependenciesMETA-INF/MANIFEST.MF内側にそれを見ることができ

Manifest-Version: 1.0 
Archiver-Version: Plexus Archiver 
Built-By: Me 
Created-By: Apache Maven 3.3.9 
Build-Jdk: 1.8.0_102 
Main-Class: HelloWorld 

:ようmaven-assembly-pluginによって作成されたマニフェストに見えます。このファイルには"Implementation-Version"というプロパティはありません。これは正常です。この実行可能なJARが作成されると、すべての依存関係のすべてのMANIFESTが(正当に)無視され、"Main-Class"を含むものを生成するだけで、JARが実行可能になります。

uber-jarには、それぞれの依存関係マニフェストの内部に何が含まれることはできません。たとえば、"Implementation-Version"は複数のライブラリのマニフェストに存在するプロパティなので、どちらを保持する必要がありますか? (最後には、ユーバージャーにはマニフェストが1つだけあります)。したがって、問題が発生するのは、実行可能なJARを作成しているからです。実行可能なJARは1つのマニフェストしか持つことができないため、それぞれの依存関係マニフェスト内のすべてのプロパティを集約できません。

2つの可能な解決策があります。

  1. はそれを無視します。結局のところ、これは実際にはエラーではありません。
  2. すべての依存関係を1つのJARに埋め込むことで実行可能なjarファイルを作成するのではなく、各依存ファイルをlibフォルダ内に作成してZIPアセンブリを作成します。この方法では、各マニフェストは保持されます。これは、maven-jar-pluginにクラスパスの追加とカスタムアセンブリ記述子の作成を伴うメインクラスのマニフェストエントリの追加を指示することによって行われます。ZIPファイルartifactId-version-dist.zipを作成するmvn clean installを実行して、このような構成により

    <assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd"> 
        <id>dist</id> 
        <formats> 
        <format>zip</format> 
        </formats> 
        <dependencySets> 
        <dependencySet> 
         <outputDirectory>lib</outputDirectory> 
         <useProjectArtifact>true</useProjectArtifact> 
        </dependencySet> 
        </dependencySets> 
    </assembly> 
    

    /path/to/assembly.xmlがあるPOMの場所に相対組立ディスクリプタへのパスを、ある

    <plugin> 
        <artifactId>maven-jar-plugin</artifactId> 
        <version>3.0.2</version> 
        <configuration> 
         <archive> 
          <manifest> 
           <mainClass>${mainClass}</mainClass> 
           <addClasspath>true</addClasspath> 
          </manifest> 
         </archive> 
        </configuration> 
    </plugin> 
    <plugin> 
        <artifactId>maven-assembly-plugin</artifactId> 
        <version>2.6</version> 
        <executions> 
         <execution> 
          <phase>package</phase> 
          <goals> 
           <goal>single</goal> 
          </goals> 
         </execution> 
        </executions> 
        <configuration> 
         <descriptors> 
          <descriptor>/path/to/assembly.xml</descriptor> 
         </descriptors> 
        </configuration> 
    </plugin> 
    

    。それを開梱し、実行している

    java -jar lib\<finalName>.jar 
    

    が問題なくバージョンを表示します(あなたのJARのfinalName<finalName>を置き換えます)。

+0

偉大な答え、非常に明確です。ユーザーがプログラムを実行するのがより困難になるので、私は2番目の選択肢があまり好きではありません。メインジャーにジャーを入れるオプションはありますか?それは働くだろうか?また、LWJGLは特定のクラスが初期化されたときに静的ブロックでこれらのメソッドを呼び出すため、LWJGLはオプションではありません(実際のライブラリハッシュとマニフェストに格納されている値を比較するLibaryコールcheckHash())。 – Frithjof

+0

@Frithjofメインjar内のライブラリjarを含むNoは機能しません。 jarはリソースとして扱われ、クラスに含まれるクラスはクラスパスには含まれません(http://stackoverflow.com/q/183292を参照)。 2番目のオプションでは、最初のオプションと同じくらい簡単です.ZIPを展開し、以前と同じコマンドを実行する必要があります。多くのジャーが懸念されているので(実行するのを混乱させる)、ZIPのルートにシェルスクリプト( 'start.bat' /' start.sh')を追加して、このシェルを実行することができます代わりにスクリプト。 (Mavenディストリビューション自体がバンドルされているのとまったく同じです。) – Tunaki

+0

@Frithjofもう一つの解決策は、メインアーティファクトを 'lib'フォルダー内でなくZIPのルートの外側にすることです。それで 'java -jar finalName.jar'を実行することができ、' lib'の中身について心配する必要はありません。変更が必要です:1.アセンブリ記述子で ' false'( 'true'の代わりに)2.記述子に ' $ {project.build.directory}/$ {project.finalName } .jar/ 'Jar Pluginの設定で' lib 'を追加してください。 – Tunaki

関連する問題