我最近遇到了glassfish standalone(v3.1)vs glassfish embedded(v3.1)vs java SE以及java.endorsed.dirs的使用方式。我遇到的具体问题是here,但我不认为这是我最后一次碰到类似的事情。
我发现here和here的信息建议在编译时将glassfish认可的lib添加到bootstrap类路径中。但是,this错误报告表明,在使用glassfish嵌入时,很难正确设置已认可的库。
所以,似乎当我部署到一个独立的glassfish容器时,我的应用程序将针对glassfish包含的认可库运行,但是当使用嵌入式容器时它不会。我遇到了我原来的问题,因为maven-embedded-glassfish-plugin没有启动使用像glassfish独立的认可库这样嵌入的glassfish。我也不确定其他容器(例如:jboss)是否包含与glassfish相同的认可库。
所以,我(1)应该努力(很多)确保我的应用程序是针对认可的lib编译的,并且总是部署到使用被认可的libs引导的容器,或者我应该(2)坚持使用Java SE 6捆绑的东西?
如果我选择(2),在将应用程序部署到使用较新认可的libs引导的容器时,是否需要担心不兼容性?
我很感激任何人都可以提供的任何见解。
答案 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>
......但这是错误的。原因是实际运行的程序称为ForkedBooter
,ForkedBooter
以编程方式为单元测试设置系统属性。也就是说,当<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}
${settings.localRepository}
将扩展到本地Maven存储库所在的值。${file.separator}
是一种在Maven属性替换中获取System.getProperty("file.separator")
值的方法。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很可能会破裂。
干杯,