使用命令行对java程序的编译运行和打包

时间:2022-02-11 17:42:54

0x00 背景

我们平时使用了在有IDE的环境下编写代码,编译的工作会由IDE自动完成,这样方便了我们工作,但是却使我们忽略了代码是如何执行的本质,或者当电脑上只有jre环境,没有开发环境,就需要在cmd环境下进行java程序的编译和运行,本文详细介绍了如何在cmd环境下使用命令行执行java程序。

0x01 使用javac和java编译和执行java程序

1、Java源程序经过编译器编译后编成字节码,即class文件中的内容,字节码由虚拟机解释执行,虚拟机将每一条要执行的字节码送给解释器,解释器将其翻译成特定机器上的机器码,然后在特定的机器上运行。代码开头是可以不带有包名的,比如在D:\workspace\src中建立Demo.java,代码如下:

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

方法一:进入文件所在盘符,输入d:,再输入cd workspace/src进入java源程序的根目录,输入命令javac Demo.java对Demo.java程序进行编译,生成Demo.class文件,再输入命令java Demo运行Demo.class文件,随后即可看到程序运行的结果。注意:程序的编译和运行最好在项目的根目录下,比如此例进入src这个目录进行编译和运行。如图所示:
使用命令行对java程序的编译运行和打包
方法二:因为在Windows系统中盘符是以反斜杠分隔的,即“\”,所以编译的时候在windows系统中也可以使用反斜杠作为分隔符,进入文件所在盘符,输入d:,然后输入命令javac workspace\src\Demo.java ,这种方法可以在Linux系统中是不能使用的,这里写出只是为了告诉读者Windows下可以使用,但是不建议使用。
如图所示:
使用命令行对java程序的编译运行和打包

2、一般代码的开头都是带有包名的,例如程序如下:

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

那么相应的应该在路径D:\workspace\src\com\hh下存储Demo.java文件,然后使用如下方式编译和运行,注意一定要在包路径外的路径下使用java命令运行,分隔符可以使用"/"或者".",如图所示:
使用命令行对java程序的编译运行和打包
在Windows系统中可以使用反斜杠作为分隔符。如图所示: 使用命令行对java程序的编译运行和打包

0x02 java在cmd环境下编译引用第三方jar包的类

很多时候一个代码都不是独立完成的,而是需要调用第三方包的,设置classpath的目的,在于告诉Java执行环境,在哪些目录下可以找到您所要执行的Java程序所需要的类或者包。
为了方便演示,我引用了poi-3.8-20120326.jar这个第三方jar包
编写调用第三包的类文件,代码如下:

package com.hh;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;

public class Demo 
{

    public static void main(String[] args)
    {       
        Workbook wb = new HSSFWorkbook();
        System.out.println(wb.getNumberOfSheets());
    }

}

从上面调用代码中我们可以看出,调用代码的类名为:Demo,功能是新建一个excel,显示出sheet的数目,将jar包和调用程序都放在D:\workspace下,目录结构如图所示:
使用命令行对java程序的编译运行和打包
执行命令如下:
使用命令行对java程序的编译运行和打包
当要使用的第三方jar包很多时,如果要一个一个写入classpath会很麻烦,这样可以用“*”来代替,比如:把要使用的jar包都放在D:\workspace\lib下,
那么在编译时命令为:javac -cp lib/* src/com/hh/Demo.java
运行时的命令为:java -cp src;lib/*.jar com.hh.Demo
使用命令行对java程序的编译运行和打包

0x03 将引用了第三方jar包的Java项目打包成jar文件

由于是打包引用了第三方jar包的Java项目,故需要自定义配置文件MANIFEST.MF,在该项目下建立文件MANIFEST.MF,内容如下:
Manifest-Version: 1.0
Main-Class: main.KillCheatFans
Class-Path: lib/commons-codec.jar lib/commons-httpclient-3.1.jar lib/commons-logging-1.1.jar lib/log4j-1.2.16.jar lib/jackson-all-1.8.5.jar
第一行是MAINIFEST的版本,第二行指定我们要执行的MAIN java文件,第三行Class-Path就指定了外来jar包的位置。
这里要注意几点:
1、Class-Path: 和Main-Class: 后边都有一个空格,必须加上,否则会打包失败,错误提示为:Invalid header field;

2、假设我们的项目打包后为KillCheatFans.jar,那么按照上面的定义,应该在 KillCheatFans.jar的同层目录下建立一个lib文件夹(即lib文件和打包的jar文件
在同一个目录下),并将相关的jar包放在里面。否则将会出现“Exception in thread “main” java.lang.NoClassDefFoundError”的错误;

3、Main-Class后面是类的全地址,比如你的主文件是KillCheatFans.java,文件里打包为package com.main; 那么这里就写com.main.KillCheatFans,
不要加.java后缀,主文件地址写错将会出现“找不到或无法加载主类”的错误;