2011-04-28 90 views
4

我在不同的JAR中獲得了兩個具有相同包的類。直到以前的版本,兩個類都是相同的,所以我沒有加載它們的問題。現在,他們中的一個添加了一個新的方法,如果我想訪問它,不僅要導入包中的類,還需要確保具有正確類的jar在類路徑中首先出現。在不同的JAR中加載兩個類

javac -classpath "%classpath%;a.jar;b.jar" MyClasses..

其中a.jar與我的新方法的類。

現在,當我的應用程序進入生產環境時,如何將它部署爲EAR文件,以及所有在WEB-INF/lib下的庫?

我如何知道哪個罐子比其他罐子更受歡迎?像a.jar這樣的字母順序是否比b.jar優先?

我讀過這safe-class-imports-from-jar-files線程,並瞭解了編寫自定義類加載器,但有沒有更好的更簡單的解決方案?因爲我只是要在當前項目中的整個JAR中訪問此方法並編寫類加載器似乎有點矯枉過正。

請不要問我「爲什麼地獄在同一個包裝在不同的JARs?」它的絕對不在我的控制範圍內,需要一段時間才能得到糾正。

環境詳細信息:IBM WAS 6.1在其1.5 Java上。

請問我更多的問題,如果我沒有太大的意義。提前致謝!

+0

好吧,謝謝你的答案。最後,儘管我討厭說,唯一真正的解決辦法,任何人都可以建議,是刪除重複。除此之外,我可以選擇將我的jar添加到bootclasspath或應用服務器的類路徑,但該選項似乎不可行,因爲部署不是由我完成的。我很快就會接受答案。再次感謝你。 – asgs 2011-04-28 12:04:52

回答

2

Websphere允許您在搜索類時指定特定應用程序的類加載器的查詢順序(類加載器是分層結構的,從加載JRE類的最高層到WAR中的類加載器加載類)。

在部署應用程序期間,您可以指定在搜索類時是否查詢類加載器的順序。有兩種模式 - 父類第一(即首先查詢最高類加載器)和父類最後(首先查詢應用類加載器)。這可以在EAR和WAR級別上指定。

將重複的jar打包到應用程序中的不同位置(例如,一個指向EAR的類路徑,另一個指向WAR的WEB-INF/lib),並且正確設置classloader可以解決您的問題。但是,如果兩個JAR必須位於同一級別(例如WEB-INF/lib),則無法指定加載重複類時將使用哪一個JAR。

+0

對,他們都在應用程序級別:( – asgs 2011-04-28 11:43:02

+2

將一個放在EAR的類路徑中,或者放到應用服務器的擴展類路徑中,IMO沒有其他機會可以做到這一點 – 2011-04-28 11:47:50

+2

@asgs,這對你來說基本上是一種可怕的情況。唯一的「真正的」解決方案是修復瓶子以闡明依賴關係,除非你可以做一些*真正*像在你的web應用程序中嵌入OSGi那樣的奇怪東西。這會起作用,但治療比疾病更糟糕,考慮到什麼問題 – 2011-04-28 11:57:29

3

就我所知,從WEB-INF/lib加載的jar的順序是任意的 - 我問了一個關於JBOSS的類似問題,並得到了來自RedHat的回覆,它取決於java.io.File.listFiles()返回的順序在(這不是一個有保證的順序)。

自定義類加載器將是一個選項,但你有沒有考慮重新包裝罐 - 刪除重複的類?

+0

@DaveHowes謝謝,但正如我所說,刪除重複項需要一些時間,因爲它必須經過一定程度的批准。另外,你可以發佈鏈接到你的問題?這可能會有所幫助。 – asgs 2011-04-28 11:32:52

+2

http://stackoverflow.com/questions/5727703/jboss-ordering-of-contents-of-web-inf-lib – DaveH 2011-04-28 11:35:21

+2

實現這一目的的一種方法可能是將「正確的」jar放在應用程序服務器類路徑中,然後使用「家長優先」類加載。這將是一個脆弱的方法。 – DaveH 2011-04-28 11:37:47

1

JAR在一個應用程序中的順序很可能是按字母順序的,但應用程序的順序可能不是。此外,它取決於服務器如何處理類加載,即它是替換現有類還是跳過新類。儘管你已經說過了,但我仍然希望給出這樣的建議:在一個應用程序中部署多個JAR中的同一個類(例如,可能發生在版本化的jar中),這總是一個壞主意。你最好花時間來解決這個問題,而不是試圖加劇類加載。

+0

「絕對不在我的控制之下」...... – 2011-04-28 11:37:27

+0

@Andreas我讀過,但如前所述,我不認爲亂裝類加載是值得的。這可能是加快清理過程(以及隨之而來的審批)的原因。 - 編輯:asgs並沒有說絕對沒有辦法解決它,它似乎需要一段時間。 – Thomas 2011-04-28 11:43:54

3

您可以嘗試更改服務器的啓動腳本,並使用java -Xbootclasspath ....在Bootclasspath中指定具有正確類的jar。否則,不能保證2個jar中的哪一個會首先加載。

1

這可能會變得非常模糊,但我確實記得通過解決該問題的WAS管理控制檯並使用其Web UI重新安排相關的JAR文件來解決此問題。不知道這是否是您的案例中可接受的步驟,但值得一試所有都會失敗。

+0

我猜你是指在WAS的管理控制檯中提供的類加載模式選項。 – asgs 2011-04-28 12:07:48

1

假設您對部署有一定的控制權,請自行修復類加載。通過將它們以反向加載順序解壓縮到同一個目錄然後重新壓縮到一個新的jar中來組合有問題的jar。然後使用新的組合jar部署應用程序。沒有重複的類,問題解決了。

或者,在部署之前從瓶子中刪除dupe類。

+0

heh,你是對的,但如果我被允許的話,我會更願意這麼做的 – asgs 2011-04-28 12:00:27

+0

@jtalhborn,除了簽入文件和等待部署之外,我其實沒有任何frigging控制發生:( – asgs 2011-04-28 12:06:08

相關問題