处理Java EE和java.endorsed.dirs的最佳实践?

时间:2011-06-22 11:53:44

标签: java-ee glassfish glassfish-embedded

我最近遇到了glassfish standalone(v3.1)vs glassfish embedded(v3.1)vs java SE以及java.endorsed.dirs的使用方式。我遇到的具体问题是here,但我不认为这是我最后一次碰到类似的事情。

我发现herehere的信息建议在编译时将glassfish认可的lib添加到bootstrap类路径中。但是,this错误报告表明,在使用glassfish嵌入时,很难正确设置已认可的库。

所以,似乎当我部署到一个独立的glassfish容器时,我的应用程序将针对glassfish包含的认可库运行,但是当使用嵌入式容器时它不会。我遇到了我原来的问题,因为maven-embedded-glassfish-plugin没有启动使用像glassfish独立的认可库这样嵌入的glassfish。我也不确定其他容器(例如:jboss)是否包含与glassfish相同的认可库。

所以,我(1)应该努力(很多)确保我的应用程序是针对认可的lib编译的,并且总是部署到使用被认可的libs引导的容器,或者我应该(2)坚持使用Java SE 6捆绑的东西?

如果我选择(2),在将应用程序部署到使用较新认可的libs引导的容器时,是否需要担心不兼容性?

我很感激任何人都可以提供的任何见解。

2 个答案:

答案 0 :(得分:4)

编辑:上面的javaee-endorsed-api方法可能会运行正常,但它给了我一些意志力。我认为它不再生产或维护。此外,它所包含的pom.xml反映了它在某些时候被称为javaee-compact-api,您可以看到它们如何从中删除实现类。相比之下,樱桃挑选你想要使用的API罐子(我在下面推荐)似乎更稳定和灵活。最后,如果您仍想使用javaee-endorsed-api方法,仍然可以使用我推荐的常规方法,而是指向javaee-endorsed-api.jar

瑞恩;我刚刚在同一个旅途中梳理了你的这条长路(触及StackOverflow,java.net论坛等)。

在单元测试或集成测试期间,您需要设置java.endorsed.dirs系统属性,如您所知。

诀窍是你必须以运行测试的JVM拾取它的方式执行此操作。这取决于你如何运行Surefire。

如果由于某种原因你将Surefire设置为而不是 fork,这可能是件坏事,你应该在这里重新评估你的配置。

如果您将Surefire设置为分叉,那么您可能认为只需在java.endorsed.dirs节中包含systemPropertyVariables,就像这样:

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

......但这是错误的。原因是实际运行的程序称为ForkedBooterForkedBooter以编程方式为单元测试设置系统属性。也就是说,当<systemPropertyVariables>读取ForkedBooter节时,它已经太晚了。

可以在您的Surefire配置中使用<argLine>,如下所示:

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

现在,Surefire分叉的VM将正确设置其认可目录。现在让我们谈谈供应的价值。

您想要选择要覆盖的API。在您的情况下,javax.annotation.*是合法的选择。您希望在本地Maven存储库中提供包含相关jar的目录。

这是我使用的值:

${settings.localRepository}${file.separator}org${file.separator}glassfish${file.separator}main${file.separator}javaee-api${file-separator}javax.annotation${file.separator}${javaxAnnotationVersion}
  • Maven保证${settings.localRepository}将扩展到本地Maven存储库所在的值。
  • ${file.separator}是一种在Maven属性替换中获取System.getProperty("file.separator")值的方法。
  • 在我的情况下,我已经在the GlassFish artifact that bundles up the javax.annotation package as defined in Java EE 6上声明了<dependency>。所以我在这里构建了一个工件的路径。我还定义了一个名为javaxAnnotationVersion的属性,对我来说,该属性设置为3.1.2

完成所有这些操作后,当Surefire分配VM运行单元测试时,已签名的目录将设置为本地Maven存储库中包含容纳javax.annotation类的jar的目录,以及现在嵌入式GlassFish - 在进程中运行 - 将使用Java EE 6版本的javax.annotation类而不是Java SE 6版本。我希望这会帮助你。

答案 1 :(得分:2)

我可能会遗漏一些明显的东西,但是...... GlassFish Embbeded是不是附带了与Java EE规范兼容的库?并不是默认加载的那些库? (如果不是,请填写错误:http://java.net/jira/browse/EMBEDDED_GLASSFISH)。

我的意思是:您应该针对Java EE规范API进行编译,并让容器使用它自己的实现。

对于第一部分,如果你使用Maven,我喜欢Codehaus archetypes设置被认可的库的方式。它既干净又应用服务器不可知:

<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 EE 6 API编译项目所需的全部内容。任何符合Java EE 6的App Server都应该提供这些服务,您不应该担心它们如何使它可用于您的应用程序。

引导Java EE服务的责任应该是您的App Server。如果你尝试自己的“内部”解决方案,那么JAR Hell很可能会破裂。

干杯,