簡體   English   中英

是否可以使用 maven build 在 war 文件中只包含使用過的類?

[英]Is it possible to include only the used classes in a war file with maven build?

假設我的 pom.xml 文件中有這個依賴項:

  <dependency>
      <groupId>javax</groupId>
      <artifactId>javaee-api</artifactId>
      <version>6.0</version>
  </dependency>

當我做一個

clean install

所有 javaee-api-6.0.jar 都會包含在 WEB-INF\\lib 文件夾下的 war 文件中。

是否有可能不包含整個 jar,而只包含我使用的類及其依賴項?

這不是一個可行的選擇——至少在 maven 中不是,雖然你知道你正在使用哪些類,但你不知道你導入的每個類的依賴關系是什么——所以它可能無法滿足它的要求。 這就是為什么我們使用像 maven 這樣的工具來簡化導入庫的過程。

閱讀有關減少已建項目規模的更多信息,看看您有哪些選擇

除了 UberJAR,您最大的機會(恕我直言)是識別容器提供的庫,並為它們使用provided范圍。

您還可以集成 3rd 方工具,例如ProGuard

如果您要部署到 Java EE 應用程序服務器中,則整個 JAR 已由應用程序服務器提供,並且可以從 WAR 文件中省略。 您可以通過將其放入提供的范圍來完成此操作:

  <dependency>
      <groupId>javax</groupId>
      <artifactId>javaee-api</artifactId>
      <version>6.0</version>
      <scope>provided</scope>
  </dependency>

這使得該依賴項可用於編譯和測試執行,但不會將其打包到 WAR 中。

相比之下,試圖確定您需要哪些單獨的類,以便您只能包含它們的類文件,最終是毫無意義的努力。 JVM 僅在使用時加載類 - 即不加載未使用的類。

由於反射,通常無法在編譯時識別使用的類。 例如,考慮:

System.console().printf("Please specify the implementation class to use");
String className = System.console().readLine();
FooService service = (FooService) Class.forName(className).newInstance();
service.work();

您可以讓 JVM 記錄加載了哪些類,但是不同的執行可以使用不同的類......

您可以使用排除項

<dependency>
   <groupId>javax</groupId>
   <artifactId>javaee-api</artifactId>
   <version>6.0</version>
   <exclusion>
      <groupId>...</groupId>
      <artifactId>...</artifactId>
   </exclusion>
</dependency>

但我認為你不能在班級級別排除。 這僅排除在項目中存在沖突依賴項時有用的依賴項。

在我看來,這真的不是一個可行的選擇,因為在運行時幾乎不可能知道所有類的內部結構,除非您看到您正在使用的所有第 3 部分 api 的實現。

我還認為 maven 背后的整個想法是簡化開發和構建過程,這樣您就不必做任何努力來識別運行時或編譯時所需的工件。 Maven 會自動為你解決這個問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM