jar / war 能帶著 configuration 一起其實是把雙面刃:好處是開發人員能提供一種「預設組態」期待在任何環境都可運作;壞處則是非改不可又不會改的時候變成累贅。這時我們就可以思考如何因應這些情境:
- 組態內容預期在任何環境都適用
- 組態內容必須為各環境調整
- 開發人員為各環境提供不同的 jar / war 包含各自的組態內容
- 部署人員為單一的 jar / war 修改組態以適應其環境
首先看 2-1 情境:開發人員可以在 Jenkins 封裝 jar / war 之前用一個 Ant Task 讀環境變數,並將結果取代掉該改的地方,例如在 cas/src/main/resources/application.properties 有一行內容如下:
- cas.server.name=https://acme.com
但這行右邊的內容每次都不一樣,可先修正為:
- cas.server.name=https://@hostName@
當然只有這樣並不夠,必須搭配 build.xml,內容如下:
- <?xml version="1.0" encoding="UTF-8"?>
- <project default="replaceToken">
- <property environment="env" />
- <target name="replaceToken">
- <replace file="cas/src/main/resources/application.properties" token="@hostName%" value="@{env.hostName}" />
- </target>
- </project>
另外,在 Jenkins Build 段落必須在編譯封裝 jar / war(假設是用 Gradle)之前安排:
- Build
- Inject environment variables
- Invoke ant
- Invoke Gradle script
當然,實際上要再進一步整合到純粹用 Ant 或 Gradle,不再混搭會更好。
再來是情境 2-2「一個 jar / war 到處使用」,藉由很基本的 JDK 工具即可:
- mkdir working
- cd working
- mv ~/Downloads/cas-1.0.0-SNAPSHOT.war .
- jar xf cas-1.0.0-SNAPSHOT.war WEB-INF/classes/application.properties
- vi WEB-INF/classes/application.properties(改成適合環境的內容)
- jar uf cas-1.0.0-SNAPSHOT.war WEB-INF/classes/*
- mv cas-1.0.0-SNAPSHOT.war ~/Downloads
- cd ..
- rm -rf working
有的環境只有 JRE 但沒有 JDK,需要為此下載安裝嗎?別急,找找有沒有 zip / unzip 也可當做替代品:
- unzip cas-1.0.0-SNAPSHOT.war WEB-INF/classes/application.properties
- zip -u cas-1.0.0-SNAPSHOT.war WEB-INF/classes/*