Spring應用如何打包爲可執行的jar

  本文將介紹,如何將 Spring 應用如何打包爲可執行的 jar ,以及在打包、執行 jar 中遇到的問題和解決方案。

場景:

  現有一需求,需要把通過 Spring + MyBatis + Maven 構建的非 Web 應用,打包爲一個 jar 包,提供給線上通過 java 命令來執行。

問題及解決方案

1. 打包插件的選擇

  正常方式搭建、開發 Spring、MyBatis 等相關代碼和依賴。構建完成後,重點注意 pom.xml 文件中 build 標籤內的插件。

使用含 bug 的 maven-assembly-plugin

   assembly 插件在通過 mvn clean package 打包完成後,運行jar包文件,由於在公司內網,會報一些 spring.xml 文件內,**.xsd 文件找不到的問題,如
通配符的匹配很全面, 但無法找到元素 ‘context:component-scan’ 的聲明 同類型的錯誤。

  關於 ** .xsd 文件的加載細節,可以參考這篇文章的介紹
在這裏插入圖片描述
在這裏插入圖片描述
  當我們發現 jar 包在執行時,**.xml 拋出一些 **.xsd 文件找不到的錯誤時,可以打開 jar 包,./META-INF/spring.schemas 文件中查看,是否含有需要的 xsd 文件及對應的文件。

推薦使用 maven-shade-plugin 打包

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-shade-plugin</artifactId>
  <version>2.4.3</version>
  <executions>
    <execution>
      <phase>package</phase>
      <goals>
        <goal>shade</goal>
      </goals>
      <configuration>
        <transformers>
          <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
            <resource>META-INF/spring.handlers</resource>
          </transformer>
          <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
            <resource>META-INF/spring.schemas</resource>
          </transformer>
          <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
            <mainClass>com.xxx.MainClass</mainClass>
          </transformer>
        </transformers>
      </configuration>
    </execution>
  </executions>
</plugin>

配置完 pom 後,調用 mvn clean install 命令進行構建,所有的 **.xsd 文件都會被打包,並以 key-value 的形式,記錄在 ./META-INF/spring.schemas 文件中。所有的 **.xsd 文件都在這個文件裏記錄了存儲路徑,如果沒有,應用將會通過網絡地址去查找,如果還是查找不到,就會拋出對應的錯誤。

  構建成功後 target 目錄,生成2個jar包,一個爲:original-XXX-0.0.1-SNAPSHOT.jar,另一個爲:XXX-0.0.1-SNAPSHOT.jar。其中 original…jar裏只包含了工程自己的class文件,而另外的一個jar包則包含了工程本身以及所有依賴的jar包的class文件。

  我們只需要使用第二個jar包就可以了。

2. jar 包內配置文件訪問的問題

   jar包內的配置文件,已經不能使用 new File(“filePath”) 方式來尋找了,因爲文件路徑已經變成 ** .jar!/ **,這種格式並不是文件資源定位符的格式。
   如果需要讓 jar 中的代碼讀取到自己的資源文件,可以通過 YourClassName.class.getResourceAsStream("/abc.conf"); 方法來獲取到文件的輸入流,進而獲取到文件內容。

  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章