Gradle 打的Jar包,如何配置Jar包运行的时候指定resources目录
- 更新: 写的太抽象了,导致我自己回顾的时候都不知道在说些什么,其实主要注意gradle的配置使用了kotlin,与groovy有一定区别。找个时间修改一下吧。
- 主要思想是通过官方的distribution、application插件生成的springboot启动脚本,修改该脚本的启动参数,指定springBoot的resources文件存放位置;为此,需要剔除jar包内部的resources目录,以及指定resources存放位置。
- 网上资料这么少。估计是因为大家都用cicd,比较少关注这一部分内容了。
打Jar包通常情况下会将配置文件一起打包到Jar包中,这很方便,只要执行java -jar ...
就可以了,但现实往往是需要经常的去修改那个配置文件,解压再打包很不人性。比较合理的方案应该是可以将配置文件目录放在jar包外面。
这看起来是一个很常见的问题,但是我在网上找了一天才找到比较满意的结果。解压后的目录为:
my-app/
├── bin/
│ ├── my-app
│ └── my-app.bat
├── config/
│ ├── application.yml
│ └── logback.xml
└── lib/
├── my-app-1.0-SNAPSHOT.jar
├── lib1.jar
├── lib2.jar
└── ...
结论
先说结论:只需要在CLASSPATH环境变量中指定该Jar外部的resources目录就可以达到该目的
为此需要做如下三件事:
- 生成Jar包的时候剔除内部的resources目录
- 将Jar包内的resources目录文件拷贝到外部的resources目录
- 设置环境变量
插件
在这里使用到了gradle的两个官方插件:
plugins {
... ...
distribution
application
}
....
application {
mainClass.set("your.main.class")
}
distribution: 打压缩包 https://docs.gradle.org/current/userguide/distribution_plugin.html application:打Jar包 https://docs.gradle.org/current/userguide/application_plugin.html
distribution不仅可以打压缩包,还能生成启动脚本,我们的环境变量就可以在里面设置。
剔除内部的resources目录
剔除的目的是防止冲突,这不多说
tasks.jar {
exclude{it.file.toPath().startsWith("$buildDir/resources/main") }
}
拷贝resources目录到外部目录config
这里我指定的外部目录名称为config
,将它放在压缩包中
distributions {
main {
contents {
from("src/main/resources") {
into("config")
}
}
distributionBaseName.set("YourName")
}
}
修改环境变量
由于distributions插件生成一个启动jar包的shell(unix link)和bat(windows)脚本, 所以我们直接操作修改这两个文件
生成的这两个文件中,有一个CLASSPATH环境变量,指向了所有Jar包,我们只需要在后面加上:$APP_HOME/config
或者:$APP_HOME\\config
即可
...
CLASSPATH=....:$APP_HOME/config
...
gradle distributions中的CreateStartScripts
可以设置配置生成启动脚本的逻辑,但遗憾的是,操作他会覆盖我们原有的环境变量,得不偿失。不过还好,stackoverflow有人给出了解决方案:
tasks.startScripts {
classpath = classpath?.plus(files("src/dist/XxxAPlaceHolderForAConfigxxX"))
doLast {
val windowsScriptFile = file(getWindowsScript())
val unixScriptFile = file(getUnixScript())
windowsScriptFile.writeText(windowsScriptFile.readText().replace("%APP_HOME%\\lib\\XxxAPlaceHolderForAConfigxxX", "%APP_HOME%\\config"))
unixScriptFile.writeText(unixScriptFile.readText().replace("\$APP_HOME/lib/XxxAPlaceHolderForAConfigxxX", "\$APP_HOME/config"))
}
}
注意:我这里用了kotlin语言, 与groovy不太一样, 方案来自stackoverflow,可以直接看原文: https://stackoverflow.com/questions/27968376/gradle-copy-resources-processresources
最终结果
运行gradle distZip
, 在build/distributions
中会生成一个zip压缩包,对这个压缩包进行解压可以看到如下结果,执行脚本文件放在了bin中,配置文件放在了config中, lib是运行的jar包和依赖包。
把这个压缩包扔到生产环境中,解压->修改配置->执行 就OK了
#gradle(1)评论