目录
- 零、背景
- 一、合并jar包
- 1.1、自定义一组jar包
- 1.2、自定义合并jar的任务
- 1.3、定义打包jar的任务
- 二、发布jar包
- 2.1、未合并jar包之前的合并方式
- 2.2、合并jar包之后的合并方式
- 三、发现问题
- 3.1、确定gradle中的依赖关系
- 3.2、对比maven是否缺失依赖
- 3.3、对比合并前后的pom.xml
- 3.4、额外上传pom文件
零、背景
有2个gradle工程,分别是sdk-jni和java-sdk,后者静态依赖前者。
dependencies {
compile fileTree(dir: 'libs', includes: ['*jar'])
...
}
还有一些应用层的java工程,通过gradle动态依赖它们。起初,应用层工程需要分别添加sdk-jni和java-sdk这2个依赖。
为了保持java-sdk依旧静态依赖sdk-jni的前提下,需要合并sdk-jni.jar到java-sdk.jar中,这样,各应用层工程只需要引入java-sdk一个依赖即可。
一、合并jar包
1.1、自定义一组jar包
自定义一组jar包,分别是java-sdk本身的jar和sdk-jni本身的jar,为后续的合并中备用,
dependencies {
configurations {
customJars
}
customJars files('dist/apps/chain-java-sdk-' + project.version + '-raw.jar', 'dist/lib/chain-sdk-jni-' + project.version + '.jar')
...
}
1.2、自定义合并jar的任务
自定义gradle任务mergeJars,将第一步中准备好的这一组中间产物jar(chain-java-sdk-v2.2.4-raw.jar和chain-sdk-jni-v2.2.4.jar)合并为最终产物chain-java-sdk-v2.2.4.jar,
task mergeJars(type: Jar) {
archiveFileName = 'chain-java-sdk-' + project.version + '.jar'
destinationDir = file('dist/apps/')
from {
configurations.customJars.collect {it.isDirectory() ? it : zipTree(it)}
}
doLast {
def dependencies = project.configurations.customJars.files
dependencies.each { dependency ->
copy {
from zipTree(dependency)
into temporaryDir
}
}
from temporaryDir
}
}
1.3、定义打包jar的任务
定义gradle任务jar,将java-sdk本身打包为纯粹的不包含sdk-jni的jar包,名为chain-java-sdk-v2.2.4-raw.jar,并通过finalizedBy
使得执行jar任务后自动执行合并的任务,
jar {
archiveName "chain-java-sdk-" + project.version + "-raw" + '.jar'
exclude '**/*.xml'
exclude '**/*.properties'
doLast {
copy {
from destinationDirectory
into 'dist/apps'
}
copy {
from configurations.runtimeClasspath
into 'dist/lib'
}
copy {
from file('src/test/resources/config-example.toml')
from file('src/test/resources/clog.ini')
from file('src/test/resources/log4j.properties')
into 'dist/conf'
}
}
}
jar.finalizedBy mergeJars
二、发布jar包
2.1、未合并jar包之前的合并方式
定义publishing
任务,将java-sdk本身的jar包发布到maven仓库,
publishing {
publications {
maven(MavenPublication) {
from components.java
}
}
repositories {
maven {
url = version.endsWith("-SNAPSHOT") ?
"http://192.168.1.231:8081/repository/maven-snapshots" :
"http://192.168.1.231:8081/repository/maven-releases"
print url
//认证用户和密码
credentials {
username 'nexus'
password 'Nexus@123'
}
}
}
}
2.2、合并jar包之后的合并方式
合并sdk-jni到java-sdk之后,无法再通过publishing
任务,将合并后的jar包发布到maven仓库,我们选择通过mvn deploy:deploy-file
命令手动上传合并后的jar包,
mvn deploy:deploy-file -DgroupId=com.szh.chain.java-sdk -DartifactId=chain-java-sdk -Dversion=2.2.4-SNAPSHOT -Dpackaging=jar -Dfile=/Users/songzehao/Downloads/chain-java-sdk-2.2.4.jar -Durl=http://192.168.1.231:8081/repository/maven-snapshots/ -DrepositoryId=deploySnapshot
执行这一步,必须保证maven的配置文件settings.xml
定义好maven库的信息,
<?xml version="1.0" encoding="utf-8"?>
<settings>
<localRepository>/opt/maven_repo/szh_repo</localRepository>
<offline>false</offline>
<pluginGroups>
<!--
<pluginGroup>com.snda.toolkit.plugins
</pluginGroup>
<pluginGroup>com.meidusa.toolkit.plugins
</pluginGroup> -->
<pluginGroup>org.mortbay.jetty</pluginGroup>
</pluginGroups>
<mirrors>
<!-- <mirror>
<id>central</id>
<name>Central</name>
<url>http://repo1.maven.org/maven2</url>
<mirrorOf>central</mirrorOf>
</mirror>
-->
</mirrors>
<servers>
<server>
<id>deployRelease</id>
<username>nexus</username>
<password>Nexus@123</password>
</server>
<server>
<id>deploySnapshot</id>
<username>nexus</username>
<password>Nexus@123</password>
</server>
</servers>
<profiles>
<profile>
<id>szhMaven</id>
<repositories>
<repository>
<id>deployRelease</id>
<url>http://192.168.1.231:8081/repository/maven-releases/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>deploySnapshots</id>
<url>http://192.168.1.231:8081/repository/maven-snapshots/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>szhMaven</activeProfile>
</activeProfiles>
</settings>
三、发现问题
合并jar包并手动上传jar包后,发现应用层构建会缺失依赖cn.hutool:hutool-all:5.5.1。
3.1、确定gradle中的依赖关系
implementation
不会传递依赖,api
会传递依赖。自Gradle3之后,等同于api
的compile
不推荐使用,避免传递太多,导致构建太慢。
经确认,缺失的这些依赖是从java-sdk中预期要被传递进来的。也就是说,合并jar包导致gradle传递依赖失效。
3.2、对比maven是否缺失依赖
因为之前在maven工程中使用过mvn deploy:deploy-file
来手动上传包,没有出现过缺失依赖的问题,所以简单写个maven工程来验证是否能成功传递依赖到maven应用层工程。经验证,maven工程中可以成功传递依赖,而在gradle工程中不能成功传递依赖进来。
3.3、对比合并前后的pom.xml
合并之前确认是可以成功传递依赖到应用层的gradle工程,合并之后失败,所以登录nexus对比前后的jar包相关的区别。
合并之后的maven仓库中,java-sdk的pom文件内容:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.szh.chain.java-sdk</groupId>
<artifactId>chain-java-sdk</artifactId>
<version>2.2.4-SNAPSHOT</version>
</project>
合并之前的maven仓库中,java-sdk的pom文件内容:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<!-- This module was also published with a richer model, Gradle metadata, -->
<!-- which should be used instead. Do not delete the following line which -->
<!-- is to indicate to Gradle or any Gradle module metadata file consumer -->
<!-- that they should prefer consuming it instead. -->
<!-- do_not_remove: published-with-gradle-metadata -->
<modelVersion>4.0.0</modelVersion>
<groupId>com.szh.chain.java-sdk</groupId>
<artifactId>chain-java-sdk</artifactId>
<version>2.2.2-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.5.1</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<artifactId>logback-classic</artifactId>
<groupId>ch.qos.logback</groupId>
</exclusion>
<exclusion>
<artifactId>brave-tests</artifactId>
<groupId>io.zipkin.brave</groupId>
</exclusion>
</exclusions>
</dependency>
...
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.33</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<artifactId>logback-classic</artifactId>
<groupId>ch.qos.logback</groupId>
</exclusion>
<exclusion>
<artifactId>brave-tests</artifactId>
<groupId>io.zipkin.brave</groupId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
对比出来了明显的差异,合并后的pom文件只有java-sdk本身的坐标,缺失了自己需要传递出去的其他包的依赖。
3.4、额外上传pom文件
解决方案是需要在通过mvn deploy:deploy-file
手动上传jar包的同时,添加-DpomFile
参数一起上传pom文件即可。
那么一个依赖很复杂的gradle工程,如何快速得到对应的pom.xml文件?gradle提供了publishToMavenLocal
命令,执行后得到build/publications/pom-default.xml
。
所以调整上传命令:
mvn deploy:deploy-file -DgroupId=com.szh.chain.java-sdk -DartifactId=chain-java-sdk -Dversion=2.2.4-SNAPSHOT -Dpackaging=jar -Dfile=/Users/songzehao/Downloads/chain-java-sdk-2.2.4.jar -Durl=http://192.168.1.231:8081/repository/maven-snapshots/ -DrepositoryId=deploySnapshot -DpomFile=/Users/songzehao/Downloads/pom-default.xml
上传完毕再次查看maven仓库中的pom.xml,已经有完整的依赖关系。重新构建应用层的gradle工程,已经可以成功拉取到传递的依赖包。最后还是建议尽量少用静态依赖。