Redian新闻
>
dependency version collision problem
avatar
dependency version collision problem# Java - 爪哇娇娃
F*n
1
这个多年来一直是个头痛的问题, 经常碰到 dependencies 里 A 用了 C-version1, B
用了C-version2, 如果C-version1和C-version2不兼容将会产生Runtime Errors。根源
还是API设计有错误, 如果两个版本的CLASS, MEHODS不兼容, 那就应该改名而不是用同
一个名字。
目前我的solution是把source code找来全部Rename,SUN自己也是这么干的,非常Ugly
, 不知道有什么更好的办法。一个办法是在JVM level 对 identifiers 加namespace,
但显然这需要改Java Spec.
avatar
c*t
2
JVM 是允许多版本的 class 在同一 jvm 里。具体办法就是通过 ClassLoader 来
搞定。
比如 URLClassLoader acl 的 parent 是 app ClassLoader,然后 url 是 A 的
path,那么 acl 具体 class 的寻找都是 A 和 app 的。acl load 的 class 的
classloader 的 parent 是 acl 。
同时,app 里面可以有另一个 ClassLoader bcl 的 parent 是 app ClassLoader,
url 是 B 的 path 。acl 和 bcl 的 search path 不同,load 的 class 也就不同。
所以前一段时间有人问,是否能在同一 app 里同时执行多个 java application
(而且每个 application 都有自己的一套 globals),其实就可以用这个方法。
至于 sun 的问题,估计是因为 rt.jar 属于 system classloader,这个是所有
的 classloader 的 parent,那没办法。


【在 F****n 的大作中提到】
: 这个多年来一直是个头痛的问题, 经常碰到 dependencies 里 A 用了 C-version1, B
: 用了C-version2, 如果C-version1和C-version2不兼容将会产生Runtime Errors。根源
: 还是API设计有错误, 如果两个版本的CLASS, MEHODS不兼容, 那就应该改名而不是用同
: 一个名字。
: 目前我的solution是把source code找来全部Rename,SUN自己也是这么干的,非常Ugly
: , 不知道有什么更好的办法。一个办法是在JVM level 对 identifiers 加namespace,
: 但显然这需要改Java Spec.

avatar
g*g
3
If C is your code, change A or B. If C is third party code,
maybe Maven can help.

B
Ugly

【在 F****n 的大作中提到】
: 这个多年来一直是个头痛的问题, 经常碰到 dependencies 里 A 用了 C-version1, B
: 用了C-version2, 如果C-version1和C-version2不兼容将会产生Runtime Errors。根源
: 还是API设计有错误, 如果两个版本的CLASS, MEHODS不兼容, 那就应该改名而不是用同
: 一个名字。
: 目前我的solution是把source code找来全部Rename,SUN自己也是这么干的,非常Ugly
: , 不知道有什么更好的办法。一个办法是在JVM level 对 identifiers 加namespace,
: 但显然这需要改Java Spec.

avatar
F*n
4
All A, B and C are third party. One of the most encountered "C" in my
projects is lucene, which is notorious in terms of backward compatibility
and however used by a lot of tools.
Maven cannot help in this case. Maven can only help you specify which
version a dependency is. But it cannot do anything if a collision is
detected.

【在 g*****g 的大作中提到】
: If C is your code, change A or B. If C is third party code,
: maybe Maven can help.
:
: B
: Ugly

avatar
F*n
5
Good:)

【在 c*****t 的大作中提到】
: JVM 是允许多版本的 class 在同一 jvm 里。具体办法就是通过 ClassLoader 来
: 搞定。
: 比如 URLClassLoader acl 的 parent 是 app ClassLoader,然后 url 是 A 的
: path,那么 acl 具体 class 的寻找都是 A 和 app 的。acl load 的 class 的
: classloader 的 parent 是 acl 。
: 同时,app 里面可以有另一个 ClassLoader bcl 的 parent 是 app ClassLoader,
: url 是 B 的 path 。acl 和 bcl 的 search path 不同,load 的 class 也就不同。
: 所以前一段时间有人问,是否能在同一 app 里同时执行多个 java application
: (而且每个 application 都有自己的一套 globals),其实就可以用这个方法。
: 至于 sun 的问题,估计是因为 rt.jar 属于 system classloader,这个是所有

avatar
m*t
6
This is viable for "data holder classes" (IOW beans), but might become
burdensome
for APIs, because except for one of the versions, you cannot have compile-
time
dependencies on the other versions, and have to call all their APIs via
reflection.
My 2 cents.

【在 c*****t 的大作中提到】
: JVM 是允许多版本的 class 在同一 jvm 里。具体办法就是通过 ClassLoader 来
: 搞定。
: 比如 URLClassLoader acl 的 parent 是 app ClassLoader,然后 url 是 A 的
: path,那么 acl 具体 class 的寻找都是 A 和 app 的。acl load 的 class 的
: classloader 的 parent 是 acl 。
: 同时,app 里面可以有另一个 ClassLoader bcl 的 parent 是 app ClassLoader,
: url 是 B 的 path 。acl 和 bcl 的 search path 不同,load 的 class 也就不同。
: 所以前一段时间有人问,是否能在同一 app 里同时执行多个 java application
: (而且每个 application 都有自己的一套 globals),其实就可以用这个方法。
: 至于 sun 的问题,估计是因为 rt.jar 属于 system classloader,这个是所有

avatar
c*t
7
There is a workaround.
Basically, refactor code that interacts with A to X, B to Y. Usually
one doesn't call X or Y directly, but rather hooked up using interfaces
or fixed static functions through some kind of injection mechanism.
The ClassLoader stuff can be dealt with during the injection.

【在 m******t 的大作中提到】
: This is viable for "data holder classes" (IOW beans), but might become
: burdensome
: for APIs, because except for one of the versions, you cannot have compile-
: time
: dependencies on the other versions, and have to call all their APIs via
: reflection.
: My 2 cents.

avatar
F*n
8
Yes, I have been thinking about a solution since studying what you posted.
It completely possible to write a custom class loader that maps a third-
party API to its own dependencies codebase. Actually it's pretty elegant.
The inventor of Java was much smarter than me, that's for sure:)

【在 c*****t 的大作中提到】
: There is a workaround.
: Basically, refactor code that interacts with A to X, B to Y. Usually
: one doesn't call X or Y directly, but rather hooked up using interfaces
: or fixed static functions through some kind of injection mechanism.
: The ClassLoader stuff can be dealt with during the injection.

相关阅读
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。