ftp4j jar maven依赖_jar包的多层级maven依赖的坑与正确传递方法

这个问题简述起来就是项目加载jar包但是无法加载jar包的依赖

这是一个maven的特性吗?

问题发生前

程序猿经常自己写一些库实现或收集常用的逻辑方法(算法和设计模式等等),以方便多个项目使用,避免重复编码。本猿现在有这么一个库,本猿把他叫 E库 , E库用maven做工程和生命周期管理,以便能用到其他java工程中。同时库里面也引用了其他一些开源公共库,使用或包装他们以实现自己的功能。(如下是E库部分依赖截图)

本猿新建一个项目A,并引入这个自用的库,如果项目人多会用私库,多数情况不会超过5个人的,一般本猿会用项目中的文件夹做仓库。在项目A的pom.xml中加入这个文件夹做的仓库:

minimal-maven-repository

file:///${project.basedir}/minimal-maven-repository

default

true

true

这里就用minimal-maven-repository这个文件夹做仓库。

现在,在项目A根目录执行如下命令把E库部署到这个仓库中:

VERSION=1.2.0-snapshot

mvn deploy:deploy-file -Dfile=/server/data/ejoker/target/ejoker-${VERSION}.jar -DgroupId=pro.jiefzz -DartifactId=ejoker -Dversion=${VERSION} -Dpackaging=jar -Durl=file:./minimal-maven-repository/ -DrepositoryId=minimal-maven-repository -DupdateReleaseInfo=true

如果用Nexus私库的话,上面这一步相当于把jar发布到私库,并在项目中引入私库地址。

其中:

选项

用途

-Dfile

指明部署的库的路径

-DgroupId

设置库的groupId

-DartifactId

设置库的唯一artifactId

-Dversion

设置当前要部署库的版本

-Dpackaging

部署的类型

-Durl

仓库的位置,这里用项目里的一个文件夹做仓库

-DrepositoryId

仓库的id,这个选项在部署到中央仓库时有用,这里自便

-DupdateReleaseInfo

(字面意思理解)

如无意外大概会看到如下结果,即代表成功:

[INFO] Scanning for projects...

[INFO]

[INFO] ------------------------------------------------------------------------

[INFO] Building willdelete 0.0.1-SNAPSHOT

[INFO] ------------------------------------------------------------------------

[INFO]

[INFO] --- maven-deploy-plugin:2.7:deploy-file (default-cli) @ willdelete ---

Downloading: http://maven.aliyun.com/nexus/content/groups/public/org/codehaus/plexus/plexus-utils/1.5.6/plexus-utils-1.5.6.pom

Downloaded: http://maven.aliyun.com/nexus/content/groups/public/org/codehaus/plexus/plexus-utils/1.5.6/plexus-utils-1.5.6.pom (6 KB at 2.2 KB/sec)

Downloading: http://maven.aliyun.com/nexus/content/groups/public/org/codehaus/plexus/plexus/1.0.12/plexus-1.0.12.pom

Downloaded: http://maven.aliyun.com/nexus/content/groups/public/org/codehaus/plexus/plexus/1.0.12/plexus-1.0.12.pom (10 KB at 10.4 KB/sec)

Downloading: http://maven.aliyun.com/nexus/content/groups/public/org/codehaus/plexus/plexus-utils/1.5.6/plexus-utils-1.5.6.jar

Downloaded: http://maven.aliyun.com/nexus/content/groups/public/org/codehaus/plexus/plexus-utils/1.5.6/plexus-utils-1.5.6.jar (245 KB at 199.1 KB/sec)

Uploading: file:./minimal-maven-repository/pro/jiefzz/ejoker/1.2.0-snapshot/ejoker-1.2.0-snapshot.jar

Uploaded: file:./minimal-maven-repository/pro/jiefzz/ejoker/1.2.0-snapshot/ejoker-1.2.0-snapshot.jar (427 KB at 21306.2 KB/sec)

Uploading: file:./minimal-maven-repository/pro/jiefzz/ejoker/1.2.0-snapshot/ejoker-1.2.0-snapshot.pom

Uploaded: file:./minimal-maven-repository/pro/jiefzz/ejoker/1.2.0-snapshot/ejoker-1.2.0-snapshot.pom (398 B at 194.3 KB/sec)

Downloading: file:./minimal-maven-repository/pro/jiefzz/ejoker/maven-metadata.xml

Uploading: file:./minimal-maven-repository/pro/jiefzz/ejoker/maven-metadata.xml

Uploaded: file:./minimal-maven-repository/pro/jiefzz/ejoker/maven-metadata.xml (314 B at 153.3 KB/sec)

[INFO] ------------------------------------------------------------------------

[INFO] BUILD SUCCESS

[INFO] ------------------------------------------------------------------------

[INFO] Total time: 5.570 s

[INFO] Finished at: 2019-09-26T21:29:43+08:00

[INFO] Final Memory: 8M/99M

[INFO] ------------------------------------------------------------------------

查看下minimal-maven-repository目录看看:

Jiefzzs-MacBook-Pro:willdelete kimffy$ tree minimal-maven-repository/

minimal-maven-repository/

└── pro

└── jiefzz

└── ejoker

├── 1.2.0-snapshot

│   ├── ejoker-1.2.0-snapshot.jar

│   ├── ejoker-1.2.0-snapshot.jar.md5

│   ├── ejoker-1.2.0-snapshot.jar.sha1

│   ├── ejoker-1.2.0-snapshot.pom

│   ├── ejoker-1.2.0-snapshot.pom.md5

│   └── ejoker-1.2.0-snapshot.pom.sha1

├── maven-metadata.xml

├── maven-metadata.xml.md5

└── maven-metadata.xml.sha1

4 directories, 9 files

是不是跟你在别的仓库中看到的结构是一样的啊,仓库就是按这个结构装jar的。

现在,可以在项目A的pom.xml中引入E库以及一些项目中用到的库了:

log4j

log4j

1.2.17

org.slf4j

slf4j-log4j12

1.7.16

pro.jiefzz

ejoker

1.2.0-snapshot

org.apache.httpcomponents

httpclient

4.5.8

接下来,eclipse中

右键点击项目 -> maven -> update project

正常通过没毛病。

接下来在代码中使用项目A的写一段代码,并在里面用上E库:

package pro.jiefzz.willdelete;

import pro.jiefzz.ejoker_support.rocketmq.DefaultMQConsumer;

import pro.jiefzz.ejoker_support.rocketmq.MQInstanceHelper;

/**

* Hello world!

*

*/

public class App

{

public static void main( String[] args )

{

// System.out.println( "Hello World!" );

// 这个其实是E库中创建rocketmq客户端的一个助手类,没什么特别的逻辑的。

DefaultMQConsumer createDefaultMQConsumer = MQInstanceHelper.createDefaultMQConsumer("", "127.0.0.1:9876", null);

}

}

问题发生了

然后运行项目App主类:

鹅?! 找不到类?是本猿打开方式不对吗? 命令中敲一次mvn -Dmaven.test.skip=true clean compile package

-_-! 还真找不到啊。。。

java.lang.NoClassDefFoundError: org/apache/rocketmq/client/consumer/AllocateMessageQueueStrategy

这个明显是rocketmq的,而这个rocketmq的依赖不是E库带着的吗(参考上面的图)?难道本猿还要在项目A的pom.xml中贴一次E库的依赖吗?(其实本猿是故意调用E库中使用有依赖其他jar的代码的😈)

为什么E库的依赖没有被加载到项目A中?

为什么会酱

终端里看一下依赖树 mvn dependency:tree

[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ willdelete ---

[INFO] pro.jiefzz:willdelete:jar:0.0.1-SNAPSHOT

[INFO] +- junit:junit:jar:3.8.1:test

[INFO] +- pro.jiefzz:ejoker:jar:1.2.0-snapshot:compile

[INFO] \- org.apache.httpcomponents:httpclient:jar:4.5.10:compile

[INFO] +- org.apache.httpcomponents:httpcore:jar:4.4.12:compile

[INFO] +- commons-logging:commons-logging:jar:1.2:compile

[INFO] \- commons-codec:commons-codec:jar:1.11:compile

[INFO] ------------------------------------------------------------------------

[INFO] BUILD SUCCESS

[INFO] ------------------------------------------------------------------------

有点不好看,不要紧 大概就是 willdelete依赖了3个包,其中httpclient 下有3个依赖包,而junit和ejoker就直接是末端,没有更下层的依赖了

eclipse里面看到的是一个意思的。很明显,E库(就是这里的ejoker包)下应该有一些依赖啊(例如rocketmq客户端的,以及前面贴了图的)

这个问题以前就出过,只不过那时没闲管他,直接把E库的依赖往项目A里贴一次(相当于手动提供了😹)

今天刷了很久的Google没找到(以前找过也没找到),找到的都是把依赖的直接跟目标jar打到一起(不管是解压后吧class放到一起还是装到提个lib文件夹里面然后把classpath写到META-INF/mainifest.mf里面,这两殊途同归,行话叫打胖包和打瘦包),都不是本猿要的。

其实问题出在上面那个deploy到本地仓库的过程,

mvn deploy过程里有个参数 -DgeneratePom,默认值是true的 -_-**

那他干了些啥呢?看刚刚那个本地仓库的目录

Jiefzzs-MacBook-Pro:willdelete kimffy$ tree minimal-maven-repository/

minimal-maven-repository/

└── pro

└── jiefzz

└── ejoker

├── 1.2.0-snapshot

│   ├── ejoker-1.2.0-snapshot.jar

│   ├── ejoker-1.2.0-snapshot.jar.md5

│   ├── ejoker-1.2.0-snapshot.jar.sha1

│   ├── ejoker-1.2.0-snapshot.pom

│   ├── ejoker-1.2.0-snapshot.pom.md5

│   └── ejoker-1.2.0-snapshot.pom.sha1

├── maven-metadata.xml

├── maven-metadata.xml.md5

└── maven-metadata.xml.sha1

4 directories, 9 files

看看里面的ejoker-1.2.0-snapshot.pom :

Jiefzzs-MacBook-Pro:willdelete kimffy$ cat minimal-maven-repository/pro/jiefzz/ejoker/1.2.0-snapshot/ejoker-1.2.0-snapshot.pom

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

4.0.0

pro.jiefzz

ejoker

1.2.0-snapshot

Jiefzzs-MacBook-Pro:willdelete kimffy$

这段按人话说就是:这是个包。然后。。 然后没了。 没了?! 是的,没别的了,项目端的maven获得的信息就只有这丁点儿。无语....

他不是E库的pom.xml吧,是那个隐含的-DgeneratePom=true参数的杰作吧...

问题就是这里,maven不知道他还要依赖。一些纯工具类库没有其他依赖的,这样当然不会出问题,他不需要依赖,maven也没为他加载依赖。也有些需要依赖的但是项目中同时又用到了的,似乎没问题,但是只是恰巧遇上刚刚而已,如依赖log类最好理解了 大概率项目也用库里也用。即便有依赖没加载上,回头再打个胖包也是可以的。

但是这不是本猿现在要的。

肿么办才好

既然在仓库里缺了pom.xml那就补上咯,再敲一次命令,其中补上参数-DgeneratePom=false,-Dfile=指向E库的pom.xml,执行如下:

$ mvn deploy:deploy-file -Dfile=/server/data/ejoker/pom.xml -DgroupId=pro.jiefzz -DartifactId=ejoker -Dversion=${VERSION} -Dpackaging=pom -Durl=file:./minimal-maven-repository/ -DrepositoryId=minimal-maven-repository -DupdateReleaseInfo=true -DgeneratePom=false

[INFO] Scanning for projects...

[INFO]

[INFO] ------------------------------------------------------------------------

[INFO] Building willdelete 0.0.1-SNAPSHOT

[INFO] ------------------------------------------------------------------------

[INFO]

[INFO] --- maven-deploy-plugin:2.7:deploy-file (default-cli) @ willdelete ---

Uploading: file:./minimal-maven-repository/pro/jiefzz/ejoker/1.2.0-snapshot/ejoker-1.2.0-snapshot.pom

Uploaded: file:./minimal-maven-repository/pro/jiefzz/ejoker/1.2.0-snapshot/ejoker-1.2.0-snapshot.pom (7 KB at 354.7 KB/sec)

Downloading: file:./minimal-maven-repository/pro/jiefzz/ejoker/maven-metadata.xml

Downloaded: file:./minimal-maven-repository/pro/jiefzz/ejoker/maven-metadata.xml (314 B at 27.9 KB/sec)

Uploading: file:./minimal-maven-repository/pro/jiefzz/ejoker/maven-metadata.xml

Uploaded: file:./minimal-maven-repository/pro/jiefzz/ejoker/maven-metadata.xml (314 B at 102.2 KB/sec)

[INFO] ------------------------------------------------------------------------

[INFO] BUILD SUCCESS

[INFO] ------------------------------------------------------------------------

[INFO] Total time: 0.645 s

[INFO] Finished at: 2019-09-26T22:42:18+08:00

[INFO] Final Memory: 7M/123M

[INFO] ------------------------------------------------------------------------

再看看依赖树:

全部都出来了

再跑一下主类App :

不再是刚刚的错误 而是一个RuntimeException,也就是依赖问题已经被解决,(这个运行时异常是因为本猿在createDefaultMQConsumer的第三个参数传入了null)

再附上一个Nexus私库时如果想最终项目能够继承这个依赖的话应该是这样的,下图红框的位置,同时上送你的jar和项目的pom.xml

有问题欢迎指正😂

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值