7

最近、Glassfishスタンドアロン(v3.1)、Glassfish組み込み(v3.1)、Java SE、およびjava.endorsed.dirsの使用方法で問題が発生しました。私が抱えていた特定の問題はここにありますが、私が同じようなことに遭遇するのはこれが最後ではないと思います。

ここここで見つけた情報は、コンパイル時にGlassfishが承認したライブラリをブートストラップクラスパスに追加することを示唆しています。ただし、このバグレポートは、Glassfish埋め込みを使用する場合、承認されたライブラリを正しく設定することが難しいことを示しています。

したがって、スタンドアロンのGlassfishコンテナーにデプロイすると、アプリケーションはGlassfishに含まれる承認済みのライブラリに対して実行されるように見えますが、埋め込みコンテナーを使用する場合は実行されません。maven-embedded-glassfish-pluginは、glassfishスタンドアロンのように、承認されたライブラリを使用して埋め込まれたglassfishを起動しないため、元の問題が発生しました。また、他のコンテナー(例:jboss)にGlassfishと同じ承認済みライブラリのセットが含まれているかどうかもわかりません。

したがって、私は(1)アプリケーションが承認されたライブラリに対してコンパイルされ、常に承認されたライブラリを使用してブートストラップされたコンテナにデプロイされることを確認するのに(多くの)苦労することになっていますか、それとも(2)バンドルされているものを使用することに固執する必要がありますか? Java SE 6で?

(2)を選択した場合、新しい承認済みライブラリでブートストラップされたコンテナーにアプリケーションをデプロイするときに、非互換性について心配する必要がありますか?

誰もが提供できる洞察をいただければ幸いです。

4

2 に答える 2

4

編集:上記のjavaee-endorsed-apiアプローチはおそらくうまくいくでしょうが、それは私に意欲を与えます。もう生産も維持もされていないと思います。さらに、そのpom.xml中に含まれているのは、ある時点でそれが呼び出されたことを反映しておりjavaee-compact-api、実装クラスをどのように取り除くかを確認できます。対照的に、承認済みとして使用するAPI jarをチェリーピッキングすることは(以下で推奨するように)、より安定していて柔軟性があるようです。javaee-endorsed-api最後に、それでもこのアプローチを使用したい場合は、私が推奨する一般的なアプローチを使用して、javaee-endorsed-api.jar代わりにポイントすることができます。

ライアン; 同じ旅で、これに関する長い道のり(StackOverflow、java.netフォーラムなどに触れる)をくまなく調べました。

java.endorsed.dirsご存知のように、ユニットテストまたは統合テストでは、Systemプロパティを設定する必要があります。

秘訣は、テストを実行しているJVMがそれを取得するような方法でこれを実行する必要があることです。そして、それはSurefireをどのように実行しているかによって異なります。

何らかの理由でSurefireをフォークしないように設定している場合、これはおそらく悪いことであり、ここで構成を再評価する必要があります。

java.endorsed.dirsSurefireをフォークに設定している場合は、次のように単純にsystemPropertyVariablesスタンザに含めることができると思うかもしれません。

<systemPropertyVariables>
  <java.endorsed.dirs>weWillGetToThisInAMoment</java.endorsed.dirs>
</systemPropertyVariables>

...しかし、それは間違っているでしょう。その理由は、実際に実行されているプログラムはと呼ばれるものForkedBooterであり、ForkedBooterプログラムによって単体テストのシステムプロパティを設定するためです。つまり、<systemPropertyVariables>スタンザが読み取られるまでには、ForkedBooterもう手遅れです。

ただし、Surefire構成では次のように使用できます。<argLine>

<configuration>
  <argLine>-Djava.endorsed.dirs=weWillGetToThisInAMoment</argLine>
</configuration>

これで、SurefireがフォークするVMには、承認されたディレクトリが適切に設定されます。それでは、どのような価値を提供するかについて話しましょう。

オーバーライドするAPIを選択します。あなたの場合、javax.annotation.*は正当な選択です。関連するjarを格納するローカルMavenリポジトリーのディレクトリーを提供したいとします。

これが私が使用する値です:

${settings.localRepository}${file.separator}org${file.separator}glassfish${file.separator}main${file.separator}javaee-api${file-separator}javax.annotation${file.separator}${javaxAnnotationVersion}
  • ${settings.localRepository}Mavenは、それがローカルのMavenリポジトリーが存在する場所の価値にまで拡大することを保証します。
  • ${file.separator}System.getProperty("file.separator")Mavenプロパティ置換での値を取得する方法です。
  • 私の場合、 JavaEE6で定義されているようにパッケージをバンドルするGlassFishアーティファクトで<dependency>すでに宣言しています。そこで、ここでアーティファクトへのパスを作成しました。また、という名前のプロパティを定義しました。これは、私にとってはに設定されています。javax.annotationjavaxAnnotationVersion3.1.2

これらすべてを実行すると、SurefireがVMをフォークして単体テストを実行すると、承認されたディレクトリが、javax.annotationクラスを格納するjarを含むローカルMavenリポジトリ内のディレクトリに設定され、GlassFishが埋め込まれます。プロセス-JavaSE6バージョンのjavax.annotation代わりにJavaEE6バージョンのクラスを使用します。これがお役に立てば幸いです。

于 2012-08-15T15:14:07.860 に答える
2

ここで明らかな何かが欠けているかもしれませんが...GlassFishEmbbededにはJavaEE仕様と互換性のあるライブラリが付属していませんか?そして、それらのライブラリはデフォルトでロードされていませんか?(そうでない場合は、ここでバグを埋めてください:http: //java.net/jira/browse/EMBEDDED_GLASSFISH)。

つまり、Java EE仕様のAPIに対してコンパイルし、コンテナーに独自の実装を使用させる必要があります。

最初の部分では、Mavenを使用する場合、 Codehausアーキタイプが承認されたライブラリを設定する方法が好きです。クリーンであり、アプリケーションサーバーに依存しません。

<properties>
   <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
   <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

..。

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.3.2</version>
    <configuration>
        <source>1.6</source>
        <target>1.6</target>
        <compilerArguments>
            <endorseddirs>${endorsed.dir}</endorseddirs>
        </compilerArguments>
    </configuration>
 </plugin>

..。

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>2.1</version>
    <executions>
       <execution>
            <phase>validate</phase>
            <goals>
                <goal>copy</goal>
            </goals>
            <configuration>
                <outputDirectory>${endorsed.dir}</outputDirectory>
                <silent>true</silent>
                <artifactItems>
                    <artifactItem>
                        <groupId>javax</groupId>
                        <artifactId>javaee-endorsed-api</artifactId>
                        <version>6.0</version>
                        <type>jar</type>
                    </artifactItem>
                </artifactItems>
            </configuration>
        </execution>
    </executions>
</plugin>

これは、Java EE6APIに対してプロジェクトをコンパイルするために必要なほとんどすべてです。Java EE6準拠のAppServerはこれらのサービスを提供する必要があり、アプリケーションでどのように利用できるようになるかについて心配する必要はありません。

Java EEサービスのブートストラップの責任は、アプリケーションサーバーにある必要があります。独自の「社内」ソリューションを試してみると、JAR地獄が崩壊する可能性があります。

乾杯、

于 2011-06-25T23:34:05.663 に答える