【JDK命令行 一】手动编译Java源码与执行字节码命令合集(含外部依赖引用) (2)

参数文件可以是javac命令中的部分内容,比如可以是java文件的路径列表文件,将参数保存为文本中供编译时引用,缩短执行命令长度,避免命令行参数过长报错。

可匹配源码目录下的java文件列表作为参数文件

find src -name "*.java" > sourcefiles.txt

sourcefiles.txt

Main.java PrintService.java

【JDK命令行 一】手动编译Java源码与执行字节码命令合集(含外部依赖引用)

接着就可以通过 @+sourcefiles.txt 对列表文件进行引用,放到javac命令行中

#生成字节码与源码同目录 javac @sourcefiles.txt #指定存在的目录输出字节码 javac -d target @sourcefiles.txt

当然不仅是源码列表,还可以加上参数,如图

【JDK命令行 一】手动编译Java源码与执行字节码命令合集(含外部依赖引用)

10. 编译脚本示例 10.1. Linux编译脚本 compile.sh

源码文件处在 src 目录中,创建输出目录 target, 依赖包目录 lib

在工程目录下创建如下编译脚本:

compile.sh

#!/bin/bash # 编译脚本 # @author: Hellxz #出现变量取值失败、报错立即停止 set -eu #定义变量 SOURCE=src TARGET=target LIBRARY=libs #清理历史编译结果 [ -d "${TARGET}" ] && rm -rf ${TARGET}/* #输出参数文件 echo "-d ${TARGET} -encoding utf-8" > argsfile find ${SOURCE} -name "*.java" >> argsfile #编译源文件 if [ -d "${LIBRARY}" ]; then javac -cp "${LIBRARY}/*" @argsfile else javac @argsfile fi #删除参数文件 rm -rf argsfile echo "compile success!" 10.2. Windows编译脚本 compile.bat @echo off REM 源码目录 set srcdir=src REM 目标目录 set targetdir=target REM jar包外部依赖目录 set libsdir=libs REM 清理缓存 if exist %targetdir% ( echo clean target caches... del /f /s /q %targetdir%\*.* rd /s /q %targetdir% md %targetdir% echo clean caches success! ) else ( md %targetdir% ) REM 生成参数文件 echo generating argsfile.txt echo -d %targetdir% -encoding utf-8 > argsfile.txt where -r %srcdir% *.java >> argsfile.txt echo generate argsfile success! REM 编译 echo compiling... if exist %libsdir% ( javac -cp "%libsdir%\*" @argsfile.txt ) else ( javac @argsfile.txt ) REM 删除参数文件 del /f /q /a argsfile.txt echo compile success! pause 三、执行字节码 1. java 执行字节码命令

java 命令用于执行 javac编译出的字节码文件,启动 Java 虚拟机。

java 命令语法为:

java [options] classname [args]

options:选项参数,包含Java虚拟机参数等设定

classname:字节码文件,.class 后缀的文件

args:参数,将作为 main 方法的参数传入程序中

options参考:

2. 执行字节码文件

一般而言,执行 Java 程序直接用 java 命令就可以

#执行带main方法的字节码 java mainclass 3. 执行带package的字节码

当源码中有package提示包名时,执行的class需要放在层层包名目录中,举例:

package samples; public class Main { public static void main(String[] args) { System.out.println("Hello World"); } }

编译后Main.class 的位置在 /opt/target/samples/Main.class

执行java命令就需要进到 /opt/target 下,与第一层包目录平级

cd /opt/target java samples/Main.class

不进入包名目录上级,可以设置 classpath 来指定待执行查找class的起点

java -cp /opt/target samples/Main 3. 执行有外部依赖关系的字节码

src/samples/Main.java

package samples; import com.alibaba.fastjson.JSONObject; public class Main { public static void main(String[] args) { JSONObject json = new JSONObject(); json.put("hello", "world"); System.out.println(json.toJSONString()); } }

外部依赖libs目录、源码目录src、生成class目录target,src下有一个包为samples的Main.java,如下图

【JDK命令行 一】手动编译Java源码与执行字节码命令合集(含外部依赖引用)

编译src目录源码,生成字节码到target下

javac -cp "src:libs/*" -d target $(find src -name "*.java")

【JDK命令行 一】手动编译Java源码与执行字节码命令合集(含外部依赖引用)

设置classpath,执行字节码文件

java -cp "target:libs/*" samples.Main

【JDK命令行 一】手动编译Java源码与执行字节码命令合集(含外部依赖引用)

参考资料:

https://docs.oracle.com/javase/8/docs/technotes/tools/windows/javac.html

https://docs.oracle.com/javase/8/docs/technotes/tools/windows/java.html

https://zhuanlan.zhihu.com/p/74229762

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyfzsz.html