Java JDK 常用工具命令 javac、jar、java、javaw,替换 .jar 包 class 文件

「爱情、让人受尽委屈。」 2022-04-23 18:06 456阅读 0赞

目录

javac.exe 编译

jar.exe 打包

java.exe 执行

javaw.exe 命令

替换 .jar 包 class 文件


javac.exe 编译

1、编写的 Java 源文件执行之前都需要使用 javac.exe 命令进行编译,即 *.java 编译成 *.class。

2、javac.exe 在 %JAVA_HOME%/bin 目录下,配置好环境变量后,命令行中可以直接运行。命令行中输入 javac 可以看到详细用法与参数。

  1. C:\Users\Administrator.SC-201707281232>javac
  2. 用法: javac <options> <source files>
  3. 其中, 可能的选项包括:
  4. -g 生成所有调试信息
  5. -g:none 不生成任何调试信息
  6. -g:{lines,vars,source} 只生成某些调试信息
  7. -nowarn 不生成任何警告
  8. -verbose 输出有关编译器正在执行的操作的消息
  9. -deprecation 输出使用已过时的 API 的源位置
  10. -classpath <路径> 指定查找用户类文件和注释处理程序的位置
  11. -cp <路径> 指定查找用户类文件和注释处理程序的位置
  12. -sourcepath <路径> 指定查找输入源文件的位置
  13. -bootclasspath <路径> 覆盖引导类文件的位置
  14. -extdirs <目录> 覆盖所安装扩展的位置
  15. -endorseddirs <目录> 覆盖签名的标准路径的位置
  16. -proc:{none,only} 控制是否执行注释处理和/或编译。
  17. -processor <class1>[,<class2>,<class3>...] 要运行的注释处理程序的名称; 绕过默认的搜索进程
  18. -processorpath <路径> 指定查找注释处理程序的位置
  19. -parameters 生成元数据以用于方法参数的反射
  20. -d <目录> 指定放置生成的类文件的位置
  21. -s <目录> 指定放置生成的源文件的位置
  22. -h <目录> 指定放置生成的本机标头文件的位置
  23. -implicit:{none,class} 指定是否为隐式引用文件生成类文件
  24. -encoding <编码> 指定源文件使用的字符编码
  25. -source <发行版> 提供与指定发行版的源兼容性
  26. -target <发行版> 生成特定 VM 版本的类文件
  27. -profile <配置文件> 请确保使用的 API 在指定的配置文件中可用
  28. -version 版本信息
  29. -help 输出标准选项的提要
  30. -A关键字[=值] 传递给注释处理程序的选项
  31. -X 输出非标准选项的提要
  32. -J<标记> 直接将 <标记> 传递给运行时系统
  33. -Werror 出现警告时终止编译
  34. @<文件名> 从文件读取选项和文件名

3、下面新建一个 .java 源文件,进行简单的演示:

  1. import java.util.logging.Logger;
  2. public class HelloWorld {
  3. private static Logger logger = Logger.getAnonymousLogger();
  4. public static void main(String[] args) throws InterruptedException {
  5. int count = 10;
  6. while (count > 0) {
  7. logger.info(count + " 秒后运行结束...");
  8. Thread.sleep(1000);
  9. count--;
  10. }
  11. }
  12. }

20190405091640969.gif







注意事项:.java 文件中删除调开始的 package 行,源码中最好不要有中文注释,否则编译时容易报错。

如果执行 java 命令出现:错误: 找不到或无法加载主类。解决办法是:

1)使用管理员身份打开 cmd 执行命令,如果还不行,则执行第二步后,再使用管理员打开 cmd 继续操作

2)1.8 版本JDK “删除环境CLASSPATH变量”

4、传递参数给 public static void main(String[] args) 程序入库方法(多个参数时用空格隔开):java HelloWorld param1 param2 param3

jar.exe 打包

1、jar 命令可用于将整个整个项目打包成一个 jar 包,可以看出一个 java 格式的压缩包。

2、通常有以下情况需要进行打包:

1)项目作为工具类或者其它原因需要被其它项目引用,此时可以将项目打包成 jar 文件,导入到其它项目中即可。
2)如果项目提供 Main 方法入口,需要像 exe 程序一样直接运行时,此时也应该打包成 jar 包。

3、jar 命令同样是 jdk 自带的命令,在 %JAVA_HOME%/bin 目录下可以找到。

4、jar 包中有一个 META-INF\MANIFEST.MF 文件,打包时会自动生成。manifest 是证明、货单的意思,比如程序的入口类就需要在其中指明,这样运行时才能找到程序的入口。

5、命令行直接输入 jar 可以看到详细的用法与选项:

  1. PS E:\wmx\Log> jar
  2. 用法: jar {ctxui}[vfmn0PMe] [jar-file] [manifest-file] [entry-point] [-C dir] files ...
  3. 选项:
  4. -c 创建新档案
  5. -t 列出档案目录
  6. -x 从档案中提取指定的 (或所有) 文件
  7. -u 更新现有档案
  8. -v 在标准输出中生成详细输出
  9. -f 指定档案文件名
  10. -m 包含指定清单文件中的清单信息
  11. -n 创建新档案后执行 Pack200 规范化
  12. -e 为捆绑到可执行 jar 文件的独立应用程序
  13. 指定应用程序入口点
  14. -0 仅存储; 不使用任何 ZIP 压缩
  15. -P 保留文件名中的前导 '/' (绝对路径) ".." (父目录) 组件
  16. -M 不创建条目的清单文件
  17. -i 为指定的 jar 文件生成索引信息
  18. -C 更改为指定的目录并包含以下文件
  19. 如果任何文件为目录, 则对其进行递归处理。
  20. 清单文件名, 档案文件名和入口点名称的指定顺序
  21. 'm', 'f' 'e' 标记的指定顺序相同。
  22. 示例 1: 将两个类文件归档到一个名为 classes.jar 的档案中:
  23. jar cvf classes.jar Foo.class Bar.class
  24. 示例 2: 使用现有的清单文件 'mymanifest'
  25. foo/ 目录中的所有文件归档到 'classes.jar' 中:
  26. jar cvfm classes.jar mymanifest -C foo/ .

6、下面再新建一个 HelloFriend.java 源文件,结合上面的已经编译好的 HelloWorld.class 进行打包:

  1. import java.util.logging.Logger;
  2. public class HelloFriend {
  3. private static Logger logger = Logger.getAnonymousLogger();
  4. public static void main(String[] args) throws InterruptedException {
  5. int count = 10;
  6. while (count > 0) {
  7. logger.info("ÅóÓÑÄãºÃ£¡"+count);
  8. Thread.sleep(1000);
  9. count--;
  10. }
  11. }
  12. }

2019040509433934.gif

jar -cfv hello.jar HelloFriend.class HelloWorld.class :打包成功。

java.exe 执行

1、java.exe 用于运行 java 字节码文件,由 java 虚拟机对字节码进行解释和运行。比如执行 .class 字节码文件和 .jar 程序等。同样在 %JAVA_HOME%/bin 目录下。

3、命令行直接输入 java 可以看到详细的用法与选项:

  1. PS E:\wmx\Log> java
  2. 用法: java [-options] class [args...]
  3. (执行类)
  4. java [-options] -jar jarfile [args...]
  5. (执行 jar 文件)
  6. 其中选项包括:
  7. -d32 使用 32 位数据模型 (如果可用)
  8. -d64 使用 64 位数据模型 (如果可用)
  9. -server 选择 "server" VM
  10. 默认 VM server.
  11. -cp <目录和 zip/jar 文件的类搜索路径>
  12. -classpath <目录和 zip/jar 文件的类搜索路径>
  13. ; 分隔的目录, JAR 档案
  14. ZIP 档案列表, 用于搜索类文件。
  15. -D<名称>=<值>
  16. 设置系统属性
  17. -verbose:[class|gc|jni]
  18. 启用详细输出
  19. -version 输出产品版本并退出
  20. -version:<值>
  21. 警告: 此功能已过时, 将在
  22. 未来发行版中删除。
  23. 需要指定的版本才能运行
  24. -showversion 输出产品版本并继续
  25. -jre-restrict-search | -no-jre-restrict-search
  26. 警告: 此功能已过时, 将在
  27. 未来发行版中删除。
  28. 在版本搜索中包括/排除用户专用 JRE
  29. -? -help 输出此帮助消息
  30. -X 输出非标准选项的帮助
  31. -ea[:<packagename>...|:<classname>]
  32. -enableassertions[:<packagename>...|:<classname>]
  33. 按指定的粒度启用断言
  34. -da[:<packagename>...|:<classname>]
  35. -disableassertions[:<packagename>...|:<classname>]
  36. 禁用具有指定粒度的断言
  37. -esa | -enablesystemassertions
  38. 启用系统断言
  39. -dsa | -disablesystemassertions
  40. 禁用系统断言
  41. -agentlib:<libname>[=<选项>]
  42. 加载本机代理库 <libname>, 例如 -agentlib:hprof
  43. 另请参阅 -agentlib:jdwp=help -agentlib:hprof=help
  44. -agentpath:<pathname>[=<选项>]
  45. 按完整路径名加载本机代理库
  46. -javaagent:<jarpath>[=<选项>]
  47. 加载 Java 编程语言代理, 请参阅 java.lang.instrument
  48. -splash:<imagepath>
  49. 使用指定的图像显示启动屏幕
  50. 有关详细信息, 请参阅 http://www.oracle.com/technetwork/java/javase/documentation/index.html。

4、java 命令用法1:执行类,在上面 javac、jar 命令时已经使用过了,这里只进行演示用法2:执行 jar 文件。

5、上面使用 “jar -cfv hello.jar HelloFriend.class HelloWorld.class” 打包时是没有指定默认的程序入口类的,所以直接双击 jar 文件是无法运行的,可以使用 java -cp 选项进行查找 jar 中的指定类作为程序的入口类。

2019040510120987.gif

java -cp hello.jar HelloWorld:表示以 hello.jar 中的 HelloWorld 为入口类进行运行程序。
java -cp hello.jar HelloFriend:表示以 hello.jar 中的 HelloFriend为入口类进行运行程序。
注意:最后的入口类必须是全路径,本例是因为 HelloWorld、HelloFriend 直接在根目录下,所以才这样,如实际中格式应该是:com.lct.main.HelloWorld

6、除了使用 -cp 选项指定 jar 文件中红入口类,也可以直接修改其中的 META-INF\MANIFEST.MF 清单文件,在其中添加一行指定程序主类(入口类),格式如下所示:

  1. Main-Class: com.wmx.main.HelloWorld

20190405102853819.gif

提醒:清单文件在指定了 Main-Class 之后,可以直接双击 jar 文件进行运行,如同运行 exe 文件一样。

javaw.exe 命令

1、javaw.exe 命令与 java.exe 命令在使用上完全一样,区别在于:

1)java.exe 执行文件时,会在命令行中输出程序中的所有输出信息,如 System.out.println(“xxx”) 打印的信息,以及各种日志信息,如 java.util.logging.Logger 等等。
2)javaw.exe 执行文件时,不会输出程序中的任何打印信息。
3)java.exe 运行程序后,任务管理器中进程名称为 java,javaw.exe 运行程序后,任务管理器中的进程名称为 javaw。

2、一言以蔽之:如果想在命令行中看到程序中打印信息,则可以使用 java.exe 命令。反之如果不想看到调试信息,则可以用 javaw.exe 命令。

3、下面修改 HelloWorld.java 文件,简单的演示一下 java、javaw 的区别。

  1. import java.io.File;
  2. import java.io.IOException;
  3. import java.util.Date;
  4. import java.util.logging.Logger;
  5. /**
  6. * Created by Administrator on 2019/4/5 0005.
  7. */
  8. public class HelloWorld {
  9. private static Logger logger = Logger.getAnonymousLogger();
  10. public static void main(String[] args) throws InterruptedException, IOException {
  11. int count = 1;
  12. File file;
  13. while (count <= 10) {
  14. logger.info("创建第 "+(count++) + " 个文件,总数 10 个...");
  15. file = new File(new Date().getTime() + "");
  16. file.createNewFile();
  17. Thread.sleep(1000);
  18. }
  19. }
  20. }

20190405105301655.gif

4、下面再使用 javaw.exe 命令来执行:

20190405105459468.gif

中间 java 命令输出到第 2 个之所以停了,是因为按了 Ctrl + C 强制退出程序了。
java、javaw 执行 jar 文件也是同理,不再累述。

替换 .jar 包 class 文件

1、假如生产上的服务突然出现了一个 bug,而本地开发环境的改动的内容与生产上已经很大了,一时半会没办法立即发布新版本,这个时候就可以采用替类的方式,将影响降低到最小。

2、先把生产上的 .jar 或者 .war 包下载下来。

3、本地环境找到生产版本时期的 bug 所在类的源码,然后进行修复,让 IDE 自动编译,然后找到编译后 .class 文件。

4、最后将修复后 .class 文件替换生产包中的文件。

5、替换 .class 文件时,需要注意如下:

5.1、如果是非第三方依赖包的 .class 文件,则可以使用任意压缩软件打开,然后将新的 .class 文件拖进去替换即可,如下所示。

20210523150302140.gif

5.2、如果是第三方依赖包的 .class 文件,则亲测使用 7-zip 压缩工具会有问题,启动服务时报错如下,原因是将第三方依赖包拖进目标包的时候,又被重现压缩了一次,所以导致最终服务起不来了。

  1. java.lang.IllegalStateException: Unable to open nested entry 'BOOT-INF/lib/xxx-xxx.jar'
  2. ,这个时候推荐使用 WinRAR,它有一个功能 **"不压缩直接存储的文件"**,操作如下:先第三方 jar 包提取出来,然后替换 .class 文件,最后再将第三方 jar 包替换回去。

20210523152550103.gif

winrar 压缩软件下载地址:https://www.rarlab.com/download.htm

发表评论

表情:
评论列表 (有 0 条评论,456人围观)

还没有评论,来说两句吧...

相关阅读

    相关 JDK命令工具

    双12买了深入理解Java虚拟机的书,其实在学校的时候,就看过PDF版的,但是最终还是买本书装装样子,今天说的东西是书籍提到的JDK常用命令,实验加上记录来加深一下印象。 j