合并jar包导致gradle传递依赖失效

news/2024/5/20 5:02:07 标签: 合并jar包, maven, gradle, 传递依赖, pom

目录

  • 零、背景
  • 一、合并jar包
    • 1.1、自定义一组jar包
    • 1.2、自定义合并jar的任务
    • 1.3、定义打包jar的任务
  • 二、发布jar包
  • 三、发现问题
    • 3.1、确定gradle中的依赖关系
    • 3.2、对比maven是否缺失依赖
    • 3.3、对比合并前后的pom文件
    • 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。

gradle_173">3.1、确定gradle中的依赖关系

implementation不会传递依赖api传递依赖。自Gradle3之后,等同于apicompile不推荐使用,避免传递太多,导致构建太慢。
经确认,缺失的这些依赖是从java-sdk中预期要被传递进来的。也就是说,合并jar包导致gradle传递依赖失效。

maven_176">3.2、对比maven是否缺失依赖

因为之前在maven工程中使用过mvn deploy:deploy-file来手动上传包,没有出现过缺失依赖的问题,所以简单写个maven工程来验证是否能成功传递依赖maven应用层工程。经验证,maven工程中可以成功传递依赖,而在gradle工程中不能成功传递依赖进来。

pom_178">3.3、对比合并前后的pom文件

合并之前确认是可以成功传递依赖到应用层的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本身的坐标,缺失了自己需要传递出去的其他包的依赖。

pom_239">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文件,已经有完整的依赖关系。重新构建应用层的gradle工程,已经可以成功拉取到传递的依赖包。最后还是建议尽量少用静态依赖。


http://www.niftyadmin.cn/n/4959458.html

相关文章

pdf怎么拆分成一页一页的?试试这种拆分方法

pdf怎么拆分成一页一页的&#xff1f;一些PDF文件可能会包含大量的页面&#xff0c;而你只需要其中的一部分。如果你需要将这些页面单独提取出来&#xff0c;那么拆分PDF文件将会非常有用。此外&#xff0c;拆分PDF文件还可以使您更好地管理和组织这些文件&#xff0c;便于分享…

C++信息学奥赛1119:矩阵交换行

解题思路&#xff1a;当输出时换行 解题程序&#xff1a; #include<iostream> using namespace std; int main() {int arr[5][5];// 输入矩阵元素for(int i0;i<5;i){for(int j0;j<5;j){cin>>arr[i][j];}} int n,m;cin>>n>>m;// 根据条件进行矩…

HJ106 字符逆序

描述 将一个字符串str的内容颠倒过来&#xff0c;并输出。 数据范围&#xff1a;1≤len(str)≤10000 1≤len(str)≤10000 输入描述&#xff1a; 输入一个字符串&#xff0c;可以有空格 输出描述&#xff1a; 输出逆序的字符串 示例1 输入&#xff1a; I am a student 输…

开学什么电容笔便宜又好用?ipad可以用的手写笔

如今&#xff0c;随着人们生活的智能化&#xff0c;一些人已经把传统的手提电脑换成了平板电脑。无论是用iPad画图&#xff0c;还是用来写笔记&#xff0c;我觉得它都很方便&#xff0c;但苹果的Pencil却很贵&#xff0c;很多人买不起。根据我对电容笔的深刻理解&#xff0c;如…

Pyqt5-开源工具分解功能(文本拖拽)

开源第四篇:功能实现之拖拽功能与配置文件。 写这个功能的初衷,是因为,每次调试我都要手动敲命令,太麻烦了,想偷个懒,所以直接给这功能加上了,顺便衍生出了另一个想法,配置文件自动填写相关数据。 先看个简单的拖拽功能: 很明显吧,还是比较便捷的。所以我们本章,就在…

企业文件透明加密软件——「天锐绿盾」数据防泄密管理软件系统

PC访问地址&#xff1a; 首页 一、文档透明加密软件 文档透明加密功能&#xff1a;在不影响单位内部员工对电脑任何正常操作的前提下&#xff0c;文档在复制、新建、修改时被系统强制自动加密。文档只能在单位内部电脑上正常使用&#xff0c;在外部电脑上使用是乱码或无法打…

(四)Doceke安装MySQL镜像+Docker启动MySQL容器

Doceke安装MySQL镜像/Docker启动MySQL容器 一、doceke安装MySQL镜像 切换到root用户&#xff0c;su root 。 1、启动Docker 启动&#xff1a;sudo systemctl start docker 停止&#xff1a;systemctl stop docker 重启&#xff1a;systemctl restart docker 查看docker运行…

算法通关村十二关 | 字符串转换

1. 转换小写字母 LeetCode709&#xff1a;给你一个字符串s&#xff0c;将该字符串中的大写字母转换成相同的小写字母&#xff0c;返回新的字符串。 每个字母都是有确定的ASCII的&#xff0c;可以根据码表操作子字符串&#xff0c;常见的ASCII范围是&#xff1a; a-z: 97-122, …