目录
- 零、背景
- 一、合并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.filesdependencies.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 destinationDirectoryinto 'dist/apps'}copy {from configurations.runtimeClasspathinto '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工程,已经可以成功拉取到传递的依赖包。最后还是建议尽量少用静态依赖。