因自己做一个小程序,打包为jar,编译为exe后,exe运行需要依赖java运行环境,也就是说exe和jre必须在一起。但是官网下载的jre有一百多兆,而我的exe只有几百k,因此要精简jre,删除程序不需要的部分。
精简jre
做jre/bin精简时,找了许多方法,有说使用360任务管理器查看进程使用的dll的,我试了一下,不太好用,精简完成后,一直提示找不到java运行环境;
做jre/lib精简时,找到一个方法:写脚本,输出进程使用的lib
java -jar -verbose:class client.jar >> class.txt
最终实现
上述方式感觉都很有道理,但就是不适用于我的情况。后来选择了最笨的方式,先用完整的jre运行exe,程序不要停,然后做分段式删除,正在使用的文件如果被删除会有提示。
之所以做分段式删除,而不是全选删除,依靠提示保留所需文件,是因为,有些文件可以被删除,但删除后再运行exe又会报错;分段式删除操作后,重启exe,如果启动失败,则恢复刚刚删除的文件,再缩小范围执行删除。
运行异常解决
按照上述方式精简后,exe可以正常启动,但运行时会出现一些报错。出现报错可参考下列解决办法。
(转自:https://blog.csdn.net/weixin_34150503/article/details/91759106)
1.SQLServerException: 驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接。错误:“RSA premaster secret error
异常“不支持此服务器版本。目标服务器必须是 SQL Server 2000 或更高版本问题解决”
原因:用sqljdbc.jar访问SQL Server 2008时发生。
解决:用SQL Server新版本的JDBC类库sqljdbc4.jar替换旧版本的sqljdbc.jar。
异常“com.microsoft.sqlserver.jdbc.SQLServerException: 驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接。错误:“RSA premaster secret error”。”
原因:SQL Server 的JDBC jar包连接SQL Server 2008时无法建立SSL安全连接,在类路径里缺少sunjce_provider.jar包。
解决:sunjce_provider.jar一般在jre\lib\ext目录下,将其包含在CLASSPATH路径里。
参考: SQL Server JDBC 访问 SQL Server 2008 异常 ,JDBC连接SQL server 2005 驱动
2.NoClassDefFoundError: javax/crypto/BadPaddingException
解决方法如下(在linux中运行):
find / -name *.jar | while read f; do (jar tf $f | grep BadPaddingException && echo $f) &done
找到/usr/local/java/jre/lib/ jce.jar,然后放入精简JRE的lib目录中即可。
3.java.lang.SecurityException: SHA MessageDigest not available
Update 3: the -verbose:class showed that the package sun.security.provider and more does not get loaded. I dont know why though, because both alternatives are loading classes from jsse.jar where the missing package comes from, and both print [Opened C:\Program Files\Java\jre7\lib\jsse.jar]
weird behaviour of custom system classloader and MessageDigest
上文提到了jsse.jar,SUN的SHA消息摘要算法实现是在此包,程序的加密功能依赖。
4.Could not initialize class javax.crypto.JceSecurity
JIRA throws exception 'Could not initialize class javax.crypto.SunJCE_b'
原因:JVM在加载加密包时出错。
方案:确保以下jar包处于JRE_HOME目录中
JRE/lib/security/local_policy.jar
JRE/lib/security/US_export_policy.jar
5.java.lang.UnsatisfiedLinkError: no management in java.library.path
解决:add management.dll to jre\bin
6.MissingResourceException: Can't find bundle for base name com/sun/rowset/RowSetResourceBundle
原因:jre/lib/resources.jar contains the correct resource files