java 将应用程序打成可执行的JAR包,然后使用批处理方式运行

时间:2022-01-10 15:42:48

1. jar 命令详解

jar 是随 JDK 安装的,在 JDK 安装目录下的 bin 目录中,Windows 下文件名为 jar.exe,Linux 下文件名为 jar。它的运行需要用到 JDK 安装目录下 lib 目录中的 tools.jar 文件。不过我们除了安装 JDK 什么也不需要做,因为 SUN 已经帮我们做好了。我们甚至不需要将 tools.jar 放到 CLASSPATH 中。


使用不带任何的 jar 命令我们可以看到 jar 命令的用法如下:


jar {ctxu}[vfm0M] [jar-文件] [manifest-文件] [-C 目录] 文件名 ...


其中 {ctxu} 是 jar 命令的子命令,每次 jar 命令只能包含 ctxu 中的一个,它们分别表示:


 -c 创建新的 JAR 文件包


 -t 列出 JAR 文件包的内容列表


 -x 展开 JAR 文件包的指定文件或者所有文件


 -u 更新已存在的 JAR 文件包 (添加文件到 JAR 文件包中)


 [vfm0M] 中的选项可以任选,也可以不选,它们是 jar 命令的选项参数


 -v 生成详细报告并打印到标准输出


 -f 指定 JAR 文件名,通常这个参数是必须的


 -m 指定需要包含的 MANIFEST 清单文件


 -0 只存储,不压缩,这样产生的 JAR 文件包会比不用该参数产生的体积大,但速度更快


 -M 不产生所有项的清单(MANIFEST〕文件,此参数会忽略 -m 参数


 [jar-文件] 即需要生成、查看、更新或者解开的 JAR 文件包,它是 -f 参数的附属参数


 [manifest-文件] 即 MANIFEST 清单文件,它是 -m 参数的附属参数


 [-C 目录] 表示转到指定目录下去执行这个 jar 命令的操作。它相当于先使用 cd 命令转该目录下再执行不带 -C 参数的 jar 命令,它只能在创建和更新 JAR 文件包的时候可用。


文件名 ... 指定一个文件/目录列表,这些文件/目录就是要添加到 JAR 文件包中的文件/目录。如果指定了目录,那么 jar 命令打包的时候会自动把该目录中的所有文件和子目录打入包中。


下面举一些例子来说明 jar 命令的用法:


1) jar cf test.jar test


该命令没有执行过程的显示,执行结果是在当前目录生成了 test.jar 文件。如果当前目录已经存在 test.jar,那么该文件将被覆盖。


2) jar cvf test.jar test


该命令与上例中的结果相同,但是由于 v 参数的作用,显示出了打包过程,如下:


标明清单(manifest)


增加:test/(读入= 0) (写出= 0)(存储了 0%)


增加:test/Test.class(读入= 7) (写出= 6)(压缩了 14%)


3) jar cvfM test.jar test


该命令与 2) 结果类似,但在生成的 test.jar 中没有包含 META-INF/MANIFEST 文件,打包过程的信息也略有差别:


增加:test/(读入= 0) (写出= 0)(存储了 0%)


增加:test/Test.class(读入= 7) (写出= 6)(压缩了 14%)


4) jar cvfm test.jar manifest.mf test


运行结果与 2) 相似,显示信息也相同,只是生成 JAR 包中的 META-INF/MANIFEST 内容不同,是包含了 manifest.mf 的内容


5) jar tf test.jar


在 test.jar 已经存在的情况下,可以查看 test.jar 中的内容,如对于 2) 和 3) 生成的 test.jar 分别应该此命令,结果如下;


对于 2)


META-INF/


META-INF/MANIFEST.MF


test/


test/Test.class


对于 3)


test/


test/Test.class


6) jar tvf test.jar


除显示 5) 中显示的内容外,还包括包内文件的详细信息,如:


0 Wed Jun 19 15:39:06 GMT 2002 META-INF/


86 Wed Jun 19 15:39:06 GMT 2002 META-INF/MANIFEST.MF


0 Wed Jun 19 15:33:04 GMT 2002 test/


7 Wed Jun 19 15:33:04 GMT 2002 test/Test.class


7) jar xf test.jar


解开 test.jar 到当前目录,不显示任何信息,对于 2) 生成的 test.jar,解开后的目录结构如下:


==


|-- META-INF


|  `-- MANIFEST


`-- test


`--Test.class


jar xvf test.jar


运行结果与 7) 相同,对于解压过程有详细信息显示,如:


创建:META-INF/


展开:META-INF/MANIFEST.MF


创建:test/


展开:test/Test.class


9) jar uf test.jar manifest.mf


在 test.jar 中添加了文件 manifest.mf,此使用 jar tf 来查看 test.jar 可以发现 test.jar 中比原来多了一个 manifest。这里顺便提一下,如果使用 -m 参数并指定 manifest.mf 文件,那么 manifest.mf 是作为清单文件 MANIFEST 来使用的,它的内容会被添加到 MANIFEST 中;但是,如果作为一般文件添加到 JAR 文件包中,它跟一般文件无异。


10) jar uvf test.jar manifest.mf


与 9) 结果相同,同时有详细信息显示,如:


增加:manifest.mf(读入= 17) (写出= 19)(压缩了 -11%)


2. 关于 JAR 文件包的一些技巧


1) 使用 unzip 来解压 JAR 文件


在介绍 JAR 文件的时候就已经说过了,JAR 文件实际上就是 ZIP 文件,所以可以使用常见的一些解压 ZIP 文件的工具来解压 JAR 文件,如 Windows 下的 WinZip、WinRAR 等和 Linux 下的 unzip 等。使用 WinZip 和 WinRAR 等来解压是因为它们解压比较直观,方便。而使用 unzip,则是因为它解压时可以使用 -d 参数指定目标目录。


在解压一个 JAR 文件的时候是不能使用 jar 的 -C 参数来指定解压的目标的,因为 -C 参数只在创建或者更新包的时候可用。那么需要将文件解压到某个指定目录下的时候就需要先将这具 JAR 文件拷贝到目标目录下,再进行解压,比较麻烦。如果使用 unzip,就不需要这么麻烦了,只需要指定一个 -d 参数即可。如:


unzip test.jar -d dest/


2) 使用 WinZip 或者 WinRAR 等工具创建 JAR 文件


上面提到 JAR 文件就是包含了 META-INF/MANIFEST 的 ZIP 文件,所以,只需要使用 WinZip、WinRAR 等工具创建所需要 ZIP 压缩包,再往这个 ZIP 压缩包中添加一个包含 MANIFEST 文件的 META-INF 目录即可。对于使用 jar 命令的 -m 参数指定清单文件的情况,只需要将这个 MANIFEST 按需要修改即可。


3) 使用 jar 命令创建 ZIP 文件


有些 Linux 下提供了 unzip 命令,但没有 zip 命令,所以需要可以对 ZIP 文件进行解压,即不能创建 ZIP 文件。如要创建一个 ZIP 文件,使用带 -M 参数的 jar 命令即可,因为 -M 参数表示制作 JAR 包的时候不添加 MANIFEST 清单,那么只需要在指定目标 JAR 文件的地方将 .jar 扩展名改为 .zip 扩展名,创建的就是一个不折不扣的 ZIP 文件了,如将上一节的第 3) 个例子略作改动:


jar cvfM test.zip test



[size=3]如何打jar包和运行jar包[/size]

[size=3]首先,例如c盘根目录下有类HelloWorld.java:
public class HelloWorld{
      public static void main(String[] args){
          System.out.println("Hi, Hello World!");
      }
}[/size]
[size=3]把HelloWorld.java打jar包并运行:
1。进入cmd中
2。cd .. 到c盘根目录
3。运行一下java类:javac HelloWorld.java[/size]
[size=3]
4。相同目录下建一个h.mf文件,内容如下:[/size]
[size=3]         Manifest-Version: 1.0
         Main-Class: HelloWorld
         Created-By: 1.2.2(sun Microsystems Inc.):[/size]
[size=3]       其中HelloWorld为要打包的类名。[/size]
[size=3]
5。在cmd中执行:[/size]
[size=3]       jar cfm hello.jar h.mf *.class
       其中hello为打成jar包的名称(或者cvfm)[/size]
[size=3]
6。java -jar hello.jar 即可运行。


3.jar文件打包
假设需要打包的文件如下:
classes/com/albertsong/MyApp.class
classes/com/albertsong/Aaaa.class
classes/com/albertsong/util/Bbbb.class
(其中MyApp包含main函数)
建一个mymanifest.mf 文件,内容如下:
Main-Class: com.albertsong.MyApp


建一个myjar.bat文件,内容如下:
set JAVA_HOME=C:/jsdk1.5.0_09
set PATH=%JAVA_HOME%/bin
set CLASSPATH=%JAVA_HOME%/lib/tools.jar;
jar cvfm MyApp.jar mymanifest.mf  -C classes .

这两个文件都放到和classes同一个目录,即目录结构象下面一样
MyApp/classes/com/albertsong/MyApp.class
MyApp/classes/com/albertsong/Aaaa.class
MyApp/classes/com/albertsong/util/Bbbb.class
MyApp/mymanifest.mf
MyApp/myjar.bat
然后点myjar.bat这个文件执行就可以了:)

4.执行jar文件
建一个目录MyApp/release。
将生成的MyApp.jar复制到这个目录。
在这个目录里新建一个批处理文件run.bat,内容如下:
set JAVA_HOME=C:/jsdk1.5.0_09
set PATH=%JAVA_HOME%/bin
set CLASSPATH=%JAVA_HOME%/lib/tools.jar;
javaw -jar MyApp.jar

5.其它
   1)jar cvfm MyApp.jar mymanifest.mf  -C classes .
      这行命令,最后的.一定不能掉,jar命令给出的帮助的例子是
       jar cvfm classes.jar mymanifest -C foo/ .
      但是在windows下应该改成
      jar cvfm classes.jar mymanifest -C foo/ .
      或者
      jar cvfm classes.jar mymanifest -C foo .
   2)如果应用程序比较大,可能会用到其它的库,这时可以在release目录下建一个lib
     然后在run.bat的CLASSPATH中添加用到的库。
    set CLASSPATH=%JAVA_HOME%/lib/tools.jar;lib/ccc.jar;lib/ddd.jar;
    3)如果要指定java程序使用的内存,这样
    javaw -ms100m -mx256m -jar MyApp.jar
    上面指定了使用最小100M最大256M内存。
    4)如果main函数要带参数
     javaw -ms100m -mx256m -jar MyApp.jar  arg1 arg2
    5)如果不能在控制台看到有关信息,可以用java来执行jar包
       java-ms100m -mx256m -jar MyApp.jar  arg1 arg2
     javaw在后台执行。
    6)如果bat文件一闪而过,看不到输出,可以在文件最后一行加上pause,最好 的是通过cmd.exe来运行run.bat

 

---------------------

        jnative调用delphi的DLL文件

1.下载JNative的包

JNative-1.3.2下有三个文件:JNativeCpp.dll,libJNativeCpp.so,JNative.jar。

JNativeCpp.dll拷到windows/system32目录下

libJNativeCpp.so为Linux中使用的文件

JNative.jar扩展包拷到%JAVA_HOME%/jre/lib/ext下或者导入到工程中


2.Jnative中使用到的一些类和方法

org.xvolks.jnative.Jnative:  装载dll文件,定位函数  如:Jnative native=new Jnative("dllName");
JNative(),setParameter(),setRetVal(),getRetVal() etc.

org.xvolks.jnative.pointers.Pointer: 替代本地函数中的的指针,需要先申请一块内存空间,才能创建,一般使用MemoryBlockFactory利用工厂模式进行创建.
Pointer(),dispose()

org.xvolks.jnative.pointers.memory.MemoryBlockFactory : 申请一块内存空间
createMemoryBlock()

org.xvolks.jnative.exceptions.NativeException : 抛出装载,定位等方面的异常

org.xvolks.jnative.Type : 列举和管理Jnative需要的不同的数据类,一般需要传值的时候指定所传值的类型和函数的返回值


3.使用方法

3.1. 加载dll文件

JNative可使用两种方式加载dll文件:
使用System.loadLibrary加载
使用此方法可加载系统目录中的dll文件。可以先把dll文件复制到system32目录下,使用文件前缀名作为参数来加载dll文件。
使用System.load加载
此方法参数为dll文件全路径名。

3.2. 调用函数

1、首先创建JNative对象:
JNative jnative = new JNative(dll文件名, 函数名);
2、设置返回值类型:
jnative.setRetVal(Type.INT);
3、设置参数
jnative.setParameter(0, Type.STRING, …); //设置第一个参数为字符串
jnative.setParameter(1, Type.INT, String.valueof(…));       //设置第二个参数为整数
4、执行
n.invoke();
5、获取返回值
Integer.parseInt(jnative.getRetVal());


4.一个简单的例子:

import org.xvolks.jnative.JNative;
import org.xvolks.jnative.Type;
import org.xvolks.jnative.exceptions.NativeException;

public class JNativeTest {
      public static final int messageBox(int parentHandle, String  message,
                 String caption, int buttons) throws NativeException,
                 IllegalAccessException {
              JNative n = null;
              try {
                 n = new JNative("User32.dll", "MessageBoxA"); // 常量DLL_NAME的值为User32.dll
                 // 构造JNative时完成装载User32.dll,并且定位MessageBoxA方法
                 n.setRetVal(Type.INT); // 指定返回参数的类型
                 int i = 0;
                 n.setParameter(i++, Type.INT, "" + parentHandle);
                 n.setParameter(i++, Type.STRING, message);
                 n.setParameter(i++, Type.STRING, caption);
                 n.setParameter(i++, Type.INT, "" + buttons); // 指定位置上的参数类型和值
                 n.invoke(); // 调用方法
                 return Integer.parseInt(n.getRetVal());
              } finally {
                 if (n != null)
                    n.dispose(); // 记得释放
              }
           }
      public static void main(String[] args) throws NativeException,  IllegalAccessException{
            JNativeTest.messageBox(100,"Hello jnative", "jnativetest",  1);
      }
}

--------------------

CMD下的命令收集

1. gpedit.msc-----组策略

2. sndrec32-------录音机

3. Nslookup-------IP地址侦测器

4. explorer-------打开资源管理器

5. logoff---------注销命令 

6. tsshutdn-------60秒倒计时关机命令 

7. lusrmgr.msc----本机用户和组 

8. services.msc---本地服务设置 

9. oobe/msoobe /a----检查XP是否激活 

10. notepad--------打开记事本 

11. cleanmgr-------垃圾整理 

12. net start messenger----开始信使服务 

13. compmgmt.msc---计算机管理 

14. net stop messenger-----停止信使服务 

15. conf-----------启动netmeeting 

16. dvdplay--------DVD播放器 

17. charmap--------启动字符映射表 

18. diskmgmt.msc---磁盘管理实用程序 

19. calc-----------启动计算器 

20. dfrg.msc-------磁盘碎片整理程序 

21. chkdsk.exe-----Chkdsk磁盘检查 

22. devmgmt.msc--- 设备管理器 

23. regsvr32 /u *.dll----停止dll文件运行 

24. drwtsn32------ 系统医生 

25. rononce -p ----15秒关机 

26. dxdiag---------检查DirectX信息 

27. regedt32-------注册表编辑器 

28. Msconfig.exe---系统配置实用程序 

29. rsop.msc-------组策略结果集 

30. mem.exe--------显示内存使用情况 

31. regedit.exe----注册表 

32. winchat--------XP自带局域网聊天 

33. progman--------程序管理器 

34. winmsd---------系统信息 

35. perfmon.msc----计算机性能监测程序 

36. winver---------检查Windows版本 

37. sfc /scannow-----扫描错误并复原 

38. taskmgr-----任务管理器(2000/xp/2003 

39. winver---------检查Windows版本 

40. wmimgmt.msc----打开windows管理体系结构(WMI) 

41. wupdmgr--------windows更新程序

42. wscript--------windows脚本宿主设置 

43. write----------写字板 

44. winmsd---------系统信息 

45. wiaacmgr-------扫描仪和照相机向导 

46. winchat--------XP自带局域网聊天 

47. mem.exe--------显示内存使用情况 

48. Msconfig.exe---系统配置实用程序 

49. mplayer2-------简易widnows media player 

50. mspaint--------画图板 

51. mstsc----------远程桌面连接 

52. mplayer2-------媒体播放机 

53. magnify--------放大镜实用程序 

54. mmc------------打开控制台 

55. mobsync--------同步命令 

56. dxdiag---------检查DirectX信息 

57. drwtsn32------ 系统医生 

58. devmgmt.msc--- 设备管理器 

59. dfrg.msc-------磁盘碎片整理程序 

60. diskmgmt.msc---磁盘管理实用程序 

61. dcomcnfg-------打开系统组件服务 

62. ddeshare-------打开DDE共享设置 

63. dvdplay--------DVD播放器 

64. net stop messenger-----停止信使服务 

65. net start messenger----开始信使服务 

66. notepad--------打开记事本 

67. nslookup-------网络管理的工具向导 

68. ntbackup-------系统备份和还原 

69. narrator-------屏幕“讲述人” 

70. ntmsmgr.msc----移动存储管理器 

71. ntmsoprq.msc---移动存储管理员操作请求 

72. netstat -an----(TC)命令检查接口 

73. syncapp--------创建一个公文包 

74. sysedit--------系统配置编辑器 

75. sigverif-------文件签名验证程序 

76. sndrec32-------录音机 

77. shrpubw--------创建共享文件夹 

78. secpol.msc-----本地安全策略 

79. syskey---------系统加密,一旦加密就不能解开,保护windows xp系统的双重密码 

80. services.msc---本地服务设置 

81. Sndvol32-------音量控制程序

82. sfc.exe--------系统文件检查器 

83. sfc /scannow---windows文件保护 

84. tsshutdn-------60秒倒计时关机命令 

84. tsshutdn-------60秒倒计时关机命令 

85. tourstart------xp简介(安装完成后出现的漫游xp程序) 

86. taskmgr--------任务管理器 

87. eventvwr-------事件查看器 

88. eudcedit-------造字程序 

89. explorer-------打开资源管理器 

90. packager-------对象包装程序 

91. perfmon.msc----计算机性能监测程序 

92. progman--------程序管理器 

93. regedit.exe----注册表 

94. rsop.msc-------组策略结果集 

95. regedt32-------注册表编辑器 

96. rononce -p ----15秒关机 

97. regsvr32 /u *.dll----停止dll文件运行 

98. regsvr32 /u zipfldr.dll------取消ZIP支持 

99. cmd.exe--------CMD命令提示符 

100. chkdsk.exe-----Chkdsk磁盘检查 

101. certmgr.msc----证书管理实用程序 

102. calc-----------启动计算器 

103. charmap--------启动字符映射表 

104. cliconfg-------SQL SERVER 客户端网络实用程序 

105. Clipbrd--------剪贴板查看器 

106. conf-----------启动netmeeting 

107. compmgmt.msc---计算机管理 

108. cleanmgr-------垃圾整理 

109. ciadv.msc------索引服务程序 

110. osk------------打开屏幕键盘 

111. odbcad32-------ODBC数据源管理器 

112. oobe/msoobe /a----检查XP是否激活 

113. lusrmgr.msc----本机用户和组 

114. logoff---------注销命令 

115. iexpress-------木马捆绑工具,系统自带 

116. Nslookup-------IP地址侦测器 

117. fsmgmt.msc-----共享文件夹管理器 

118. utilman--------辅助工具管理器 

119. gpedit.msc-----组策略 

120. explorer-------打开资源管理器

----------------------

VBA调用cmd命令行下执行的命令

1、启动 Windows 命令解释程序

CMD [/A | /U] [/Q] [/D] [/E:ON | /E:OFF] [/F:ON | /F:OFF] [/V:ON |  /V:OFF]
    [[/S] [/C | /K] string]
/C      执行字符串指定的命令然后中止
/K      执行字符串指定的命令但保留
/S      在 /C 或 /K 后修改字符串处理(见下)
/Q      关闭回显
/D      从注册表中停用执行 AutoRun 命令(见下)
/A      使向内部管道或文件命令的输出成为 ANSI
/U      使向内部管道或文件命令的输出成为 Unicode
/T:fg   设置前景/背景颜色(详细信息,请见 COLOR /?)
/E:ON   启用命令扩展(见下)
/E:OFF  停用命令扩展(见下)
/F:ON   启用文件和目录名称完成字符(见下)
/F:OFF  停用文件和目录名称完成字符(见下)
/V:ON   将 ! 作为定界符启动延缓环境变量扩展。如: /V:ON 会
        允许 !var! 在执行时允许 !var! 扩展变量 var。var 语法
        在输入时扩展变量,这与在一个 FOR 循环内不同。
/V:OFF  停用延迟环境扩展。

2、java中调用命令行参数

java的Runtime.getRuntime().exec(commandStr)可以调用执行cmd指令。
cmd /c dir 是执行完dir命令后关闭命令窗口。

cmd /k dir 是执行完dir命令后不关闭命令窗口。

cmd /c start dir 会打开一个新窗口后执行dir指令,原窗口会关闭。

cmd /k start dir 会打开一个新窗口后执行dir指令,原窗口不会关闭。


3、例子

Shell("command.com /c [command]", [WindowStyle])


1、执行Bat文件


Shell "batName"

2、执行java的exe文件

Shell("exeName",1)

3、执行java文件

Shell "java myJavaClass"

4、打开文件

Shell "cmd /c cmd /? > c:/cmdhelp.txt"

5、清除cookies中的文件

Shell "c:/window/system32/cmd.exe /c del ""c:/Documenmts and settings/my family/cookies/*.txt""",

6、执行exe执行文件

Shell "notepad.exe   d:/ping.txt"

----------------

        java虚拟机对类型的处理过程

当java class文件被编译为标准的二进制class类型之后,这个二进制的类型数据被导入到java虚拟机时,进行了一系列的操作。

1、装载

把二进制形式的java类型读入到java虚拟机中,装载阶段又有三个必须的步骤:

1.1 通过该类型的完全限定名,产生一个代表该数据的二进制数据流。该数据流可能遵守java class文件格式,也可能遵守其它的格式。因为所有的java虚拟机实现必须能识别Java class文件格式,但是个别的实现也可以识别其它的二进制格式。

1.2 解析这个二进制数据流为方法区内的内部数据结构。

1.3 创建一个表示该类型的java.lang.Class类的实例。

有了类型的二进制数据之后,java虚拟机必须对这些数据进行足够的处理,然后才能创建类java.lang.Class的实例对象。因此虚拟机必须把这些二进制数据解析为与实现相关的内部数据结构。

装载步骤的最终产品就是这个class类的实例对象,它成为java程序与内部数据结构之间的接口。

2、连接

该过程分为三个步骤:

2.1 验证

确认类型符合java语言的语义,并且它不会危及虚拟机的完整性。例如:

a.检查final的类不能拥有子类。

b.检查final的方法不会被覆盖。

c.确保在类型和超类型之间没有不兼容的方法声明。

d.检查所有的常量池入口相互之间一致

e.检查常量池中的所有特殊字符串是否符合格式。

f.检查字节码的完整性。

2.2 准备

java虚拟机装载一个类和它的父类,并执行了一些选择性的验证之后,就到了验证阶段。

该阶段主要是java虚拟机为类变量分配内存,设置默认初始值,在初始化之前,类变量都没有被初始化为真正的初始值,因为在准备阶段是不会执行java代码的。在该阶段,虚拟机把给类变量新分配的内存根据类型设置为默认值,也可能为一些数据结构分配内存,这样做,有效地提高了程序运行的性能。

2.3 解析

解析过程就是在类型的常量池中寻找类、接口、字段和方法的符号引用,并把这些符号引用替换成直接引用的过程。这个步骤是可选的,也可能在初始化的时候进行。

3、初始化

该步骤为类变量赋予正确的初始值,也就是程序员希望这个类变量所具备的起始值。在java代码中,一个正确的初始值是通过类变量初始化语句或者静态初始化语句给出的。

初始化一个类包含两个步骤:

a.如果类存在直接超类的话,超类还没有被初始化,就先初始化超类。

b.如果类存在一个类初始化方法,就执行此方法。