maa*_*asg 11 java jar classloader sbt-assembly
我使用sbt程序集插件将一个spark工作打包为uber-jar.该build.sbt指定可运行的主要得到的尤伯杯罐的目标
mainClass in assembly := Some("com.foo.Bar")
Run Code Online (Sandbox Code Playgroud)
正确创建程序集后,运行预期的命令:
java -jar assembly.jar
Run Code Online (Sandbox Code Playgroud)
结果是
错误:无法找到或加载主类com.foo.Bar
使用替代方法,就像java -cp assembly.jar com.foo.Bar给出相同的错误消息.
然后,我在新目录中提取了超级jar的内容.我可以看到我的com/foo/目录和Bar.class文件.从我提取的目录的根目录我尝试:
java -cp . com.foo.Bar
Run Code Online (Sandbox Code Playgroud)
我得到了正确的结果.
进一步试图找出错误的原因,我试过:
java -verbose -jar assembly.jar
Run Code Online (Sandbox Code Playgroud)
我可以看到正在加载java核心类,但我没有看到我的任何打包类被加载.
这可能有什么问题?
maa*_*asg 29
经过广泛的调查(读取:拔出头发),事实证明这种行为是由于一个INDEX.LIST平坦的jar文件META-INF落入生成的超级jar目录中的流氓造成的.
遵循JAR文件规范,INDEX.LIST如果存在,则指示要加载Jar文件中的哪些包.
为避免这种情况,我们更新mergeStrategy了规则,以避免对生成的META-INF目录造成任何污染:
case PathList("META-INF", xs @ _*) => MergeStrategy.discard
Run Code Online (Sandbox Code Playgroud)
这解决了这个问题并恢复了我的理智.
更新:
经过一些额外的搜索后,事实证明默认的合并策略需要妥善处理INDEX.LIST.当自定义合并策略包含处理该案例的案例时,此答案适用META-INF pathSpec
| 归档时间: |
|
| 查看次数: |
1501 次 |
| 最近记录: |