一个库损坏了类路径?

huangapple go评论65阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2020年9月6日 02:43:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/63757382.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定