现在手里有一个小项目Tank 其中用到了数据库所以用到了mysql驱动
1.先来看eclipse的打包过程
点击项目右键export如下图
我们风别用JAR file与Runable JAR file创建
一.先用JAR file一路点击记着查找主类 生成Tank.jar
二.再用Runable JAR file这里有三个可选项
1.这个意思是将需要的库榨取到jar里(不明白什么意思看下面的图)
2.将需要的jar和库直接导入到生成的jar中(不明白什么意思看下面的图)
3.复制需要的jar包和库提取到子目录中
将这三个依次生成的Tank1.jar Tank2.jar Tank3.jar与Tank.jar一并放到D:/JarTest 目录中,当生成Tank3.jar时多出了Tank3_lib文件夹,里面是mysql数据库驱动
三.分析
下面我们在命令行中输入java -jar Tank*.jar分别测试
Tank.jar会出现java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
Tank1.jar正常
Tank2.jar一会出现java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
Tank3.jar正常
现在我们用jd-gui分别查看jar包分别查看它的文件目录 和清单文件
1.
Tank.jar很干净只有我们写的class和清单,清单中只有我们选择的主类,没有mysql相关驱动类所以运行不起来
2.
Tank1.jar可以清楚地看出它把mysql驱动包里的所有东西与咱们自己写的class混合到了一起,还有驱动包里的services(这个东东是干啥的看我另一片转载人家的博客点击打开链接)下的java.sql.Driver也被加进去了。这时候运行正常是因为Class-path为当前路径及在jar中的mysql驱动类所以运行成功。
3.
Tank2.jar的Main-class为什么不是com.hanghang.ui.TankWindow呢?原因是加载的时候是通过org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader主类再加载com.hanghang.ui.TankWindow类。 这个com.hanghang.ui.TankWindow类可以找到的但是jdbc相关类找不到,为什么呢?
通过反编译的java代码和调试我们知道了org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader加载别的jar的时候通过URL.setURLStreamHandlerFactory(参看点击打开链接)拓展了URL的协议所以说这个 Rsrc-Main-Class当前的jdk1.8不认识所以说报错(目前认识到这里)
4.
“java.lang.SecurityException: Invalid signature file digest for Manifest main attributes” )按确定