2013-05-03 120 views
12

當使用Tomcat作爲應用程序服務器設置Java Web應用程序時,我經常會對庫的可用時間感到困惑。通過關於堆棧溢出的一些討論,我瞭解到一些庫(.jar)文件在運行時可用,而其他庫則在編譯時可用。我經常會遇到錯誤,並會通過試驗和錯誤來解決它們,將jar文件放在不同的目錄中,直到應用程序運行或編譯。最近我指出,你可以通過WEB-INF/lib文件夾在運行時提供.jar庫。我開始考慮這個問題,並有幾個問題。我在過去已經閱讀過這個主題,並且沒有找到將信息放入我容易理解和保留的環境中的來源。Java庫運行時間與編譯時間

  1. 是否存在編譯時類路徑和可以爲項目設置的運行時類路徑?

    a。 Classpath甚至是討論在運行時可用的庫的適用術語嗎?

  2. WEB-INF/lib是使庫在運行時可用的唯一方法嗎?在Tomcat中的lib文件夾是什麼在運行時可用?

  3. 這與類加載器有什麼關係?我知道創建了一個類加載器的層次結構。這些嚴格適用於運行時操作嗎?

+0

「是否有編譯時類路徑和可以爲項目設置的運行時類路徑?」我不認爲「項目」是Tomcat的概念。你在想Web應用程序還是Eclipse(或其他IDE)項目? – leonbloy 2013-05-03 16:00:23

+0

我應該將這個範圍做得更好,我將Eclipse和Tomcat考慮在內。 – 2013-05-03 16:01:42

回答

15

的編譯類路徑庫是類路徑中使用(使用javac -cp ...,或你的IDE)編譯Java源文件。源文件中引用的每個類都必須存在於編譯類路徑中,否則編譯器會抱怨它無法找到該類。

一旦編譯了類,就可以使用它們運行程序(使用java -cp ...)。顯然,源代碼直接依賴的庫應該在運行時類路徑中。但那不是全部。如果直接依賴CoolLibrary.jar,並且此庫在內部依賴於Guava.jar,那麼Guava.jar也必須位於運行時類路徑中,儘管編譯時不需要它。

Web應用程序有點特別。 servlet規範指定用於執行webapp的類路徑由部署的webapp的WEB-INF/classes目錄以及WEB-INF/lib中包含的所有jar組成。所有的webapps都可以訪問Tomcat直接提供的本地servlet和JSP jar。實際上,Tomcat的內部類(如servlet-api接口的實現類)也可用於webapp,但依賴這些類並不是一個好主意,因爲它會將webapp綁定到tomcat。

談到運行時類路徑,在webapp的情況下,有點簡化。實際上,每個webapp的類都是由tomcat通過特定的類加載器動態加載的。而這個webapp類加載器是tomcat的類加載器的孩子。因此,從理論上講,您可以直接將webapp jar放入Tomcat的classpath中,但這意味着所有的webapps都會共享這些庫,並且您在取消部署和重新部署webapps時會遇到問題。例如,每個webapp擁有一個特定的類加載器的目標是能夠在同一個JVM中使用一個依賴於Guava 11.0的應用程序,而另一個依靠Guava 12.0。請參閱the documentation

+0

因此,當我在Eclipse中打開Tomcat服務器並將其類路徑設置爲運行時類路徑時?無論如何要設置每個應用程序?我想通過在特定於應用程序的運行時類路徑中指定這些jar來避免100mb戰爭文件。 – 2013-05-03 16:10:43

+2

重要的是部署的Web應用程序。默認情況下,eclipse WTP項目中的WebContent/WEB-INF/lib下的所有jar都會自動添加到編譯類路徑(Eclipse調用構建路徑)中,並且也會使用webapp在WEB-INF/lib,由Eclipse部署者。因此,在一個典型的eclipse Web項目中,您可以將Web應用程序所需的所有庫放入WEB-INF/lib中,並將所有在運行時不需要的庫(例如單元測試庫)放入另一個目錄中,並添加到建立路徑。通常沒有理由混淆Tomcat的內部類路徑。 – 2013-05-03 16:14:21

1
  1. 在eclipse

    ,你有java build path,其中包括在編譯時庫,和你有order and export,這對於運行。

    只有
  2. tomcat的默認提供

+1

在Eclipse的'Order and Export'選項卡中,它表示'Exported entries are contribute to dependent projects'並不意味着依賴項目會將這些庫用於編譯?你確定它涉及到服務器的運行時? – 2013-05-03 16:03:29