2011-06-22 24 views
7

我最近遇到了glassfish standalone(v3.1)vs glassfish embedded(v3.1)vs java SE和使用java.endorsed.dirs的問題。我遇到的具體問題是here,但我不認爲這是我最後一次遇到類似問題。處理Java EE和java.endorsed.dirs的最佳實踐?

我發現的信息herehere建議在編譯時將glassfish批註的庫添加到引導類路徑中。但是,this錯誤報告表明,使用glassfish嵌入時很難正確設置背書庫。

所以,好像當我部署到一個獨立的GlassFish的容器我的應用程序是要針對贊同庫運行的GlassFish包括但使用嵌入式容器時,不會因。我遇到了我原來的問題,因爲maven-embedded-glassfish-plugin沒有使用像glassfish standalone這樣的背書庫來啓動glassfish。我也不確定其他容器(例如:jboss)是否包含與glassfish相同的一組背景庫。所以,我(1)應該努力(很多)來確保我的應用程序是針對背書庫進行編譯的,並且始終部署到使用背書的庫進行引導的容器,或者我應該(2)只是堅持使用與Java SE 6捆綁在一起的東西?

如果讓我選擇(2),我會擔心不兼容部署我的應用程序被自舉與新批准的庫容器中時?

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

回答

2

我可能失去了一些東西很明顯,但......是不是GlassFish的Embbeded隨與Java EE規範庫兼容?而不是默認加載的那些庫? (如果它們不是,請填寫這裏的錯誤:http://java.net/jira/browse/EMBEDDED_GLASSFISH)。

我的意思是:你應該對編譯的Java EE規範的API,只是讓容器使用它自己的實現。

在第一部分,如果你使用Maven,我喜歡Codehaus archetypes設置贊同庫的方式。它既是乾淨和Application Server不可知論:

<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有可能會失敗。

乾杯,

+0

你說的是(IMO)它應該工作的方式,但Java SE中認可庫的舊版本在加載時贏得'第一次匹配'場景..我想。啓動JVM的人需要設置java.endorsed.dirs,但對於某些嵌入式容器來說很困難。對於Glassfish Embedded,一切都在一個大的JAR中,我認爲認可的庫不保證位於特定的位置。我開始的[線程的Arquillian(http://community.jboss.org/thread/168521?tstart=0),看看他們的想法。我添加了一個[Glassfish的錯誤(http://java.net/jira/browse/EMBEDDED_GLASSFISH-131)。 –

+0

@Ryan J.我只是看看你的bug報告,它確實是可重現的。這應該由GlassFish團隊根據我以前的帖子的精神修復,但在他們能夠解決此問題之前,請通過一些快速解決方法: 1.使用Main Class啓動服務器。 2.切換到其他嵌入式容器。 3.設置贊同庫使用MAVEN_OPTS(uggly,但將讓你立刻去......)。 –

4

編輯:本javaee-endorsed-api上述做法可能會正常工作,但它讓我心驚肉跳。我認爲它不再被生產或維護。此外,其中包含的pom.xml反映了它在某個時候被稱爲javaee-compact-api,您可以看到它們如何從中除去實現類。相比之下,櫻桃採摘您要使用的API罐作爲認可(如我下面推薦)似乎更加穩定和靈活。最後,如果您仍然想要使用javaee-endorsed-api方法,則仍然可以使用我推薦的一般方法,並指向javaee-endorsed-api.jar

Ryan;我只是在同一旅程中梳理了這段長篇小說(涉及StackOverflow,java.net論壇等)。如您所知,在設備或集成測試期間,您需要設置java.endorsed.dirs系統屬性。

訣竅是你必須這樣做,運行測試的JVM纔會啓動它。這取決於你如何運行Surefire。

如果由於某種原因您將Surefire設置爲而不是 fork,這可能是一件壞事,您應該在此重新評估您的配置。

如果你有神火集到餐桌,那麼你可能會認爲你可以簡單地包括在systemPropertyVariablesjava.endorsed.dirs,像這樣:

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

...但這是錯誤的。原因在於,實際運行的程序是ForkedBooterForkedBooter以編程方式爲單元測試設置系統屬性。也就是說,當你的<systemPropertyVariables>節被ForkedBooter讀取時,它已經太晚了。

但是你可以您神火配置中使用<argLine>這樣的:

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

現在的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}將擴大到你的本地倉庫的生活,其中的價值。
  • ${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

一旦你做到了這一切,那麼當神火叉一個虛擬機來運行單元測試,獲得覈準的目錄將被設置爲你的本地倉庫目錄包含容納javax.annotation類的jar,現在它運行在進程—嵌入式GlassFish中—將使用javax.annotation類,而不是Java SE 6的版本的Java EE 6的版本。我希望這能夠幫到你。