本文主要是介绍将java项目导出成jar-exe-安装程序,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
关于将java项目导出成exe文件
第一步:通过eclipse将java项目导出成可执行的jar包
选择项目->Export>Runnable JAR file
导出之后是一个可执行的jar包,可以直接执行。接下来把jre整个文件夹复制到与jar包同目录中,同时把把项目中引用的第三方包(ceflib)拷贝到jre的bin目录中去。
第二步:精简jre
运行cmd,进入dos界面,设置java临时路径
set path=D:\HCIM2\jre6\bin;
通过jar命令运行导出来的jar包
java -jar im.jar
第一次运行时会报错提醒
这是因为导出可执行jar包是并没有导出位于项目根目录的图片和部分配置文件,我们只需要把这些文件复制到im.jar同目录中即可
接下来就是精简jre
开始时根据网上办法(http://yaojialing.iteye.com/blog/1067409)通过将项目操作到底,精简rt和charesets两个大jar文件,精简之后小了很多 具体操作如下:
通过谷歌搜索得到的精简思路:
把自己的应用程序打包成jar,然后通过jar命令运行这个jar,把jar所需的类全部打印到一个文本文件里面,把文本文件里面的类提取出来,重新打包。覆盖JRE目录中的JAR包。去掉JRE下bin目录和lib目录中不需要得。瘦身完成。
应用程序打包后是test.jar,jre(目录) 也和它同一文件夹,写一个CMD脚本方便测试:
1. @echooff
2. setpath=./jre6/bin
3. java-jar-verbose:classtest.jar>>class.txt
4. pause
这样程序使用的就是当前目录下的jre,程序运行后,最好把所有的功能使用一遍,这样输出了一个文件class.txt,里面有所有需要的class,其格式如下:
1. [OpenedD:\data\dict\jre\lib\rt.jar]
2. [Loadedjava.lang.ObjectfromD:\data\dict\jre\lib\rt.jar]
3. [Loadedjava.io.SerializablefromD:\data\dict\jre\lib\rt.jar]
4. [Loadedjava.lang.ComparablefromD:\data\dict\jre\lib\rt.jar]
5. [Loadedjava.lang.CharSequencefromD:\data\dict\jre\lib\rt.jar]
6. [Loadedorg.apache.lucene.index.CompoundFileReader$FileEntryfromfile:/D:/data/dict/dict.jar]
输出的class文件里面可能还包含其他应用的jar包,如:charsets.jar。这样就需要把class文件里面的信息按rt和charsets分成两类分别放到两个txt文件里面:rt_class.txt,charsets.txt
我们依照这个文件来裁剪rt.jar:
首先在utralEdit中进行一些处理,去掉所有不是rt.jar中的class的行,去掉from后面的,去掉loaded等无关项目,再把“.”替换成“/”.这个可以利用正则表达式等轻松处理。处理完后得到的文件类似如下格式:
rt_class.txt
1. java/lang/Object
2. java/io/Serializable
3. java/lang/Comparable
4. java/lang/CharSequence
5. java/lang/String
我们依照这个文件来裁剪charsets.jar:
首先在utralEdit中进行一些处理,去掉所有不是charsets.jar中的class的行,去掉from后面的,去掉loaded等无关项目,再把“.”替换成“/”.这个可以利用正则表达式等轻松处理。处理完后得到的文件类似如下格式:
charsets.txt
1. sun/nio/cs/ext/ExtendedCharsets
2. sun/nio/cs/ext/GBK
3. sun/nio/cs/ext/DoubleByteDecoder
4. sun/nio/cs/ext/GBK$Decoder
5. sun/nio/cs/ext/DoubleByteEncoder
6. sun/nio/cs/ext/GBK$Encoder
然后写一个脚本或者程序处理,从rt或charsets中把需要的的class拷贝到另一个对应的文件夹rt1或charsets1,这里参考网上的一个JAVA抽取程序。
在运行下面JAVA程序之前需要将JRE目录中rt.jar,charsets.jar分别解压到相应目录
代码如下:
1. packagecom.ccic.greenjvm;
2.
3. importjava.io.File;
4. importjava.io.FileInputStream;
5. importjava.io.FileOutputStream;
6. importjava.io.IOException;
7. importjava.io.InputStreamReader;
8. importjava.io.LineNumberReader;
9.
10. publicclassReduceRt{
11. //文件拷贝
12. publicstaticbooleancopy(Stringfile1,Stringfile2){
13. try//musttryandcatch,otherwidewillcompileerror
14. {
15. //instancetheFileasfile_inandfile_out
16. java.io.Filefile_in=newjava.io.File(file1);
17. java.io.Filefile_out=newjava.io.File(file2);
18. FileInputStreamin1=newFileInputStream(file_in);
19. FileOutputStreamout1=newFileOutputStream(file_out);
20. byte[]bytes=newbyte[1024];
21. intc;
22. while((c=in1.read(bytes))!=-1)
23. out1.write(bytes,0,c);
24. in1.close();
25. out1.close();
26. return(true);//ifsuccessthenreturntrue
27. }catch(Exceptione){
28. System.out.println("Error!");
29. return(false);//iffailthenreturnfalse
30. }
31. }
32.
33. //读取路径,copy
34. publicstaticintdealClass(Stringneedfile,Stringsdir,Stringodir)throwsIOException{
35. intsn=0;//成功个数
36.
37. Fileusedclass=newFile(needfile);
38. if(usedclass.canRead()){
39. Stringline=null;
40. LineNumberReaderreader=newLineNumberReader(newInputStreamReader(newFileInputStream(usedclass),
41. "UTF-8"));
42. while((line=reader.readLine())!=null){
43. line=line.trim();
44. intdirpos=line.lastIndexOf("/");
45. if(dirpos>0){
46. Stringdir=odir+line.substring(0,dirpos);
47. Filefdir=newFile(dir);
48. if(!fdir.exists())
49. fdir.mkdirs();
50. Stringsf=sdir+line+".class";
51. Stringof=odir+line+".class";
52. booleancopy_ok=copy(sf.trim(),of.trim());
53. if(copy_ok)
54. sn++;
55. else{
56. System.out.println(line);
57. }
58.
59. }
60.
61. }
62. }
63. returnsn;
64.
65. }
66.
67. publicstaticvoidmain(String[]args){
68. Stringneedfile="D:/greanjvm/rt_class.txt";//运行JAR生成的,应用程序所需类的txt文件
69. Stringsdir="D:/greanjvm/rt/";//rt.jar解压后的目录
70. Stringodir="D:/greanjvm/rt1/";//抽取的类存放目录
71. try{
72. intsn=dealClass(needfile,sdir,odir);
73. System.out.print(sn);
74. }catch(IOExceptione){
75. e.printStackTrace();
76. }
77.
78. }
79. }
所需的类都抽取到rt1目录之后,把原rt目录中的“META-INF”文件夹拷贝到rt1下面,进入rt1目录,用rar压缩工具打包成rt.zip,改名为rt.jar,然后替换jre6/lib目录下的rt.jar。
charsets1目录处理同上。
所需类的精简工作已经完成,接下来精简其他的。
1、Jre目录下的license都删除,只留bin和lib目录
2、bin下的执行文件需要运行jar时用DLL_Killer工具查看使用到了哪些文件
3、lib下只要保留 rt,charsets库就可以了(因为应用程序只用到了这两个)。
4、除了i386和zi两个子目录外,其余的子目录都可以不要(原则上都要自己试试看删除其他目录会不会报错)。
5、Zi下只需要保留自己地区的子目录和其下的一些文件就可以(这里Zi下我只保留了America文件夹)。
6、Lib下除了库之外的属性文件都要保留。
优化完成!!!!!!!!!!!
注意事项:
1、精简BIN目录
*运行JAR包时需指定PATH路径,不然会默认搜索环境变量中的JDK路径。
*用DLL_Killer工具查看任务管理器中java.exe调用的DLL库
2、精简LIB目录
*抽取出的类重新打包成rt.jar时要注意,用JAR命令和rar工具打的jar包都不行。解决如下:
-将原生的rt.jar用rar打开,然后进入相关目录,删除掉相关目录或者文件,再把抽取出来的类拖进来就行了。
*zi文件夹下只留America文件夹
个人的办法
按照上面的办法能得到一个非常精简的jre包,而事实上这个jre包却不能用,一直在提醒缺少类文件引用以及JavaThread "AWT-EventQueue-0"等错误。后来采用了一种比较笨的方法,自己逐步的删除bin目录的文件以及jre的文件,看项目是否能够正常运行,能则可以删除,反之保留。精简charsets.jar可以完全参考上述办法,而在精简rt.jar文件时可以参考着上述精简后的文件,逐步删除,尝试是否项目正常运行。
第三步:将jar打包exe文件
使用工具exe4j,在使用之前一定把exe4j注册掉,否则倒出来的exe不能执行。
参考网上方法(http://www.blogjava.net/pengo/archive/2010/03/12/315278.html)
第1步,默认即可,直接点击next。
第2步,选择"JAR inEXE",点击next
第3步,上面是项目名称,可随便填写,下面一个是把jar转成exe文件后,exe文件的输出目录(建议和原jar路径一致):第4步,HtmlFrame.jar是GUI程序,所以选第一个,Executable name是生成的exe文件的名字,Icon File可以选择是这个exe文件的图标
第5步,单击绿色的"+"号,在弹出的窗口中点Archive,然后找到HtmlFrame.jar,"OK"后返回,在下面的ClassPath里就出现jar文件路径后,再在上面Main Class栏内点击找到main()方法所在的类,这一步即算完成:第6步,确认系统的JRE版本,上面填个1.4,下面填1.6:
上边配置的程序只能在安装有JRE的机器上执行,但发布时要考虑用户的机器上是否安装有JRE,总不能发布一个程序还要用户自己安装个JRE,下面为将要生成的exe指定jre路径,在这里单击advanced options,选择searchsequence。先把Search Sequence列表内所有选项删除,再点击绿色"+",Entry Type选择Directory,再在下边的路径选择中选择HtmlFrame2\jre6,
单击ok后,再从图中单击advanced options,并选择preferred VM,在弹出的窗口中选择clienthostspot VM,单击next按钮继续:
第7步,设置程序的启动画面,单击next
第8步,设置提示消息的语言,单击next
第9步编译
第10步,完成
第四步:将整个文件夹渲染成安装程序,使用工具inno setup5
打开inno setup进行渲染。。。
当到达步骤Application Files时进行选择exe、及其他配置文件(包含jar文件等)
但选择jre6时先将jre6整个文件夹复制到一新目录中命名为jre,在选择jre时直接定位到jre文件夹,如果直接选择jre6的话,那么exe文件江河jre6中的bin文件夹和lib文件夹同目录。
以下为渲染时的脚本
; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPTFILES!
#define MyAppName "IM"
#define MyAppVersion "1.0"
#define MyAppPublisher "HnTest"
#define MyAppExeName "MyProg.exe"
[Setup]
; NOTE: The value of AppId uniquely identifies this application.
; Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{D132D0C4-1860-46E9-95CB-7EB98EC0F909}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
DefaultDirName={pf}\{#MyAppName}
DefaultGroupName={#MyAppName}
OutputBaseFilename=IM
Compression=lzma
SolidCompression=yes
[Languages]
Name: "english"; MessagesFile:"compiler:Default.isl"
[Tasks]
Name: "desktopicon"; Description:"{cm:CreateDesktopIcon}"; GroupDescription:"{cm:AdditionalIcons}"; Flags: unchecked
[Files]
Source: "D:\Program Files (x86)\Inno Setup5\Examples\MyProg.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "D:\IM_NEW\arrow_left.png"; DestDir:"{app}"; Flags: ignoreversion
Source: "D:\IM_NEW\arrow_refresh.png"; DestDir:"{app}"; Flags: ignoreversion
Source: "D:\IM_NEW\arrow_right.png"; DestDir:"{app}"; Flags: ignoreversion
Source: "D:\IM_NEW\client.properties"; DestDir:"{app}"; Flags: ignoreversion
Source: "D:\IM_NEW\Im.exe4j"; DestDir: "{app}";Flags: ignoreversion
Source: "D:\IM_NEW\im.jar"; DestDir: "{app}";Flags: ignoreversion
Source: "D:\IM_NEW\page-loader.gif"; DestDir:"{app}"; Flags: ignoreversion
Source: "D:\IM_NEW\webAddress.properties"; DestDir:"{app}"; Flags: ignoreversion
Source: "D:\IM_NEW\jre\*"; DestDir: "{app}"; Flags:ignoreversion recursesubdirs createallsubdirs
; NOTE: Don't use "Flags: ignoreversion" on any shared systemfiles
[Icons]
Name: "{group}\{#MyAppName}"; Filename:"{app}\{#MyAppExeName}"
Name: "{commondesktop}\{#MyAppName}"; Filename:"{app}\{#MyAppExeName}"; Tasks: desktopicon
[Run]
Filename: "{app}\{#MyAppExeName}"; Description:"{cm:LaunchProgram,{#StringChange(MyAppName, '&','&&')}}"; Flags: nowait postinstall skipifsilent
渲染成功,进行测试
这篇关于将java项目导出成jar-exe-安装程序的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!