英文:
A library corrupts classpath?
问题
以下是翻译好的内容:
有一个我从未见过的奇怪问题。
在我的 Gradle 项目的依赖列表中添加 compile 'org.locationtech.spatial4j:spatial4j:0.7'
会导致类路径损坏。当我注释掉那个库并运行 java -verbose:class -jar sol_backend_full.jar > ok.log
时,会输出 4399 行的类条目。然而,将该库放在类路径中时,java -verbose:class -jar sol_backend_full.jar > failed.log
只输出了 953 行,其中大多数是 java.lang.*
或 sun.*
。
这显然会导致 错误:找不到或加载主类
。
➥ 有人遇到过这种奇怪的行为吗?
当然,我可以用另一个空间库替换那个库,但正在发生的事情实在是奇怪。这只在这个库中发生,移除/添加其他任何库都没有问题。
问题中提到的 Gradle 版本是 5.5.1
,而该库的清单看起来有点长,但一点也不可疑。回退到 4.8
也会复现这个问题。
这是构建脚本:
task customFatJar(type: Jar) {
manifest {
attributes 'Main-Class': 'ru.rxproject.sol.backend.BackendApplication',
'Implementation-Version': version + System.getenv('BUILD_NUMBER').toString(),
'Commit-Hash': 'git-' + System.getenv('GIT_COMMIT'),
'Build-Date': java.time.LocalDateTime.now().toString()
}
archiveName = 'sol_backend_full.jar';
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
with jar
}
英文:
There's a strange issue I've never seen.
Adding a compile 'org.locationtech.spatial4j:spatial4j:0.7'
to the dependencies list in my gradle project leads to a corrupt classpath. When I comment out that library and run java -verbose:class -jar sol_backend_full.jar > ok.log
it outputs 4399 lines of class entries. However, with that library in classpath, java -verbose:class -jar sol_backend_full.jar > failed.log
outputs only 953 lines, most of which are java.lang.*
or sun.*
.
It obviously results in Error: Could not find or load main class
.
➥ Has anyone ever encountered that strange behaviour?
Of course, I can substitute that library with another spatial library, but what's happening is simply strange. It happens only with this library, removing/adding any other is fine.
Gradle version in question is 5.5.1
, and that library manifest looks a bit long, but not suspicious at all. Falling back to 4.8
also reproduces it.
Here is the build script:
task customFatJar(type: Jar) {
manifest {
attributes 'Main-Class': 'ru.rxproject.sol.backend.BackendApplication',
'Implementation-Version': version + System.getenv('BUILD_NUMBER').toString(),
'Commit-Hash': 'git-' + System.getenv('GIT_COMMIT'),
'Build-Date': java.time.LocalDateTime.now().toString()
}
archiveName = 'sol_backend_full.jar'
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
with jar
}
答案1
得分: 1
JAR依赖项org.locationtech.spatial4j:spatial4j:0.7是一个已签名的jar包。当您创建一个fat jar时,Java类加载器无法从您的fat jar中加载其他类,因为这些类没有被签名。
因此,您不能在保留签名的情况下创建包含该依赖项的fat jar。
请参考 - https://stackoverflow.com/q/51455197/11244881
如上述帖子中所提到的,您可以像以下这样排除签名:
jar {
manifest {
attributes "Main-Class": mainClassName
}
from {
configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
}
exclude 'META-INF/*.RSA'
exclude 'META-INF/*.SF'
exclude 'META-INF/*.DSA'
}
但是,我建议将jar依赖项排除在fat jar之外。
英文:
The JAR dependancy org.locationtech.spatial4j:spatial4j:0.7 is a signed jar. When you create a fat jar, java Classloader is not able to load the other classes from your fat jar because these are not signed.
So, you can't create a fat jar with that dependancy without excluding the signatures.
Please refer - https://stackoverflow.com/q/51455197/11244881
Like mentioned in the above post, you may exclude the signatures like -
jar {
manifest {
attributes "Main-Class": mainClassName
}
from {
configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
}
exclude 'META-INF/*.RSA'
exclude 'META-INF/*.SF'
exclude 'META-INF/*.DSA'
}
But, I would suggest to keep the jar dependancy out of the fat jar.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论