由于MANIFEST.MF不规范导致程序无法启动的问题

| Comments

昨晚发现某个jar程序启动不了,包类没找到。 这个是由于我增加了一个新的jar包,并且依赖于xwork.jar。 所以在build.xml里边增加这个jar包。

		<fatjar.build output="ibossproc.jar">
      ...
	    <fatjar.jarsource file="${buildlib}/jsse.jar" relpath=""/>
	    <fatjar.jarsource file="${buildlib}/cipher14.jar" relpath=""/>
	    <fatjar.jarsource file="${buildlib}/xwork-2.0.4.jar" relpath=""/>
    </fatjar.build>

不过还是出错,出错信息挺诡异的(用星号对某些信息进行屏蔽):

mccxj@XXX:/work/procs/log> cat *
线程 "main" 中发生异常java.lang.NoClassDefFoundError: com.*.*.*.*Entry
Caused by: java.lang.ClassNotFoundException: com.*.*.*.*Entry
        at java.net.URLClassLoader.findClass(URLClassLoader.java:421)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:652)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:346)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:618)
Could not find the main class: com.*.*.*.*Entry.  Program will exit.

这个类是程序里边的代码,应该是存在的。把jar解压了,也的确看到jar包里边有这个类。

于是把以前能跑的jar拿来进行对比,发现META-INF/MANIFEST.MF稍稍有点不同,新的在最后多了2个空行。 简单调整了一下打包脚本(用的一个fatjar.jar的工具),最后两行进行调整顺序,发现就可以了。

		<fatjar.build output="xx.jar">
      ...
	    <fatjar.jarsource file="${buildlib}/jsse.jar" relpath=""/>
	    <fatjar.jarsource file="${buildlib}/xwork-2.0.4.jar" relpath=""/>
	    <fatjar.jarsource file="${buildlib}/cipher14.jar" relpath=""/>
    </fatjar.build>

一开始感觉是fatjar.jar的bug,不过回过头来看,其实是cipher14.jar这个包的问题。
因为这个包的META-INF/MANIFEST.MF的最后一样是个问号,根据规范文档, 这个是不规范的。如:

Manifest-Version: 1.0

?

而fatjar会把所有的MANIFEST.MF进行合并,但是奇怪的地方就在这里了。如果问号是在最后一样,能够正常启动。
如果问号后面还有内容,就启动不了。所以调整顺序之后,能够正常启动。
后来,我把cipher14.jar的MANIFEST.MF中的问号去掉,不需要调整顺序也是可以正常的。

这个包应该是第三方厂商提供的,又踩地雷了。

Comments