如何使用Javac/Jar/Java工具对源代码进行编译打包执行

图片来自pixabay.com的qimono会员

Javac/Jar/Java是JDK的发布包中带的三个基本工具,用于对Java源码进行编译打包运行,本文将介绍这几个工具的使用方法。

1. 代码和演示环境

代码地址:https://gitee.com/pphh/blog/tree/master/171221_java_compile_run/
演示环境:Windows 7 SP1, JDK 9.0.1

下面的所有命令演示都是在目录./171221_java_compile_run/中进行,文件的目录结构如下,

+ Simple.java
+ src
  - App.java
  + common
    - java/com/pphh/demo/Logger.java
  + main
    - java/com/pphh/demo/AppPkg.java
+ src2
  - AppLogger.java
+ src3
  - AppJ7.java
  - AppJ8.java
+ target
  - app.jar
  - common.jar
  + classes

2. Java源码编译

在开发完Java代码后,首先需要对源码进行编译。JDK中带的编译工具为Javac。

javac的命令格式为,

javac [options] [sourcefiles]

其中:
options 命令行选项
sourcefiles 待编译的代码文件

a) 简单的编译

只需要输入代码的文件地址即可

javac ./Simple.java
java Simple

b) 指定编译后的输出目录

使用-d选项,指定编译后的class文件输入目录

javac -d ./target/classes Simple.java
javac -d ./target/classes ./src/main/java/com/pphh/demo/AppPkg.java

c) 编译某个目录下的多个代码文件

使用-sourcepath选项,指定一个代码目录,然后通过通配符*.java获取指定目录下的所有代码文件进行编译,

set src_dir=./src/common/java/com/pphh/demo/
javac -d ./target/classes -sourcepath %src_dir% %src_dir%/*.java

上述命令会将指定目录下Logger.java文件进行编译,并按照package(com.pphh.demo)放置编译好的class文件,具体位置为,
./target/classes/com/pphh/demo/Logger.class

d) 有依赖的编译

可以通过-cp选项,指定依赖的class/Jar文件或所在目录。
例如程序代码src2/AppLogger.java有对前一步产生的Logger.class有依赖,其编译命令为,

javac -cp ./target/classes -d ./target/classes src2/AppLogger.java

上述命令指定了在依赖文件目录为/target/classes,编译代码后,将在目录./target/classes中产生一个AppLogger.class文件。

e) CLASSPATH

在编译的时候,Javac会从如下几个地方查找依赖class文件,

  1. 环境变量CLASSPATH定义的依赖文件和目录
  2. 当前执行命令的目录
  3. 通过-cp/-classpath指定的依赖文件和目录

在指定依赖的时候,可以通过上述几个方法定义依赖的class文件。

f) 编译时指定源码和目标代码的Java版本

可以通过-source/-target选项指定。

javac -d ./target/classes ./src3/AppJ7.java -source 7 -target 7
javac -d ./target/classes ./src3/AppJ8.java -source 8 -target 8

在JDK 9中Javac支持的Java版本包括6, 7, 8, 9,JDK9不再支持-source 5之前的版本。

需要注意的是,源发行版必须高于目标发行版,换句话说Java 7语言级别的代码,可以编译成Java 7/8/9语言级别的目标class文件,但不能编译成Java 6语言级别目标代码。

3. class文件打包

对代码编译之后,为了方便发布和使用,需要使用工具jar对这些class文件进行打包成Jar包。Jar是Java Archives的缩写,意思为Java归档文件。

jar的命令格式为,

jar [options] [ [--release VERSION] [-C dir] files] ...

其中:
options 命令行选项
--release VERSION创建多版本的Jar包,这是JDK9新功能
-C DIR 更改目录路径

a) 简单的打包命令

在打包前,先切换到class文件目录,然后执行打包命令,

cd ./target/classes
jar cvf ../common.jar ./

上述命令将./target/classes目录下所有文件打好包为common.jar,并放置在上一层目录中,也就是./target/下面。

将common.jar放置在classes目录之外,这是为了区分class和jar包文件,防止在下一次运行命令时,将刚刚生成的common.jar也打入下一个包中,形成循环。

b) 打包时更改目录路径到根目录

很多时候我们希望直接指定class的目录路径,但是我们不要使用如下的命令,

jar cvf ./target/common.jar ./target/classes(不推荐此命令,请使用-C选项)

因为上面的命令没有更改目录结构。如果通过解压工具解压common.jar包,会发现里面classes文件目录结构是不对的,classes文件并没有放置在根目录,而且放置在target/classes/中,这个是不对的。

这个时候要使用-C选项,更改目录路径到根目录

jar -cvf ./target/common.jar -C ./target/classes/ .

c) 设置主程序

每一个Jar包都可以设置一个运行主程序,当使用Java -jar命令运行Jar包时,会自动执行这个主程序。

设置主程序要使用-e选项,

jar -cvfe ./target/common1.jar Simple -C ./target/classes/ .
jar -cvfe ./target/common2.jar AppLogger -C ./target/classes/ .
jar -cvfe ./target/common3.jar com.pphh.demo.AppPkg -C ./target/classes/ .

上面的命令将Jar包中的主程序分别设置为Simple\AppLogger\com.pphh.demo.AppPkg,包的运行见后面。

d) 选择指定的class文件打包

除了指定一个class目录,我们还可以指定某些class文件打成Jar包。

下面将指定的一个App.class打入app.jar包中,

jar -cvf ./target/app.jar -C ./target/classes/ Simple.class

下面将一个Logger.class归档为一个日志类库包中,

jar -cvf ./target/logger.jar -C ./target/classes/ ./com/pphh/demo/Logger.class

4. 执行Java程序

在将源码编译成可执行的class文件后,接下来就可以使用java工具来启动运行。

java的命令格式为,

java [options] mainclass [args...]

其中:
options 命令行选项
mainclass 主程序类文件
args 命令行参数

a) 简单的编译运行

javac Simple.java
java Simple

b) 指定class文件或目录
javac -d ./target/classes Simple.java
java -classpath ./target/classes Simple
java -classpath "./target/classes/Simple.class;" Simple
c) 运行一个在指定package的运行程序

javac -d ./target/classes ./src/main/java/com/pphh/demo/AppPkg.java
java -classpath ./target/classes com.pphh.demo.AppPkg

d) 运行一个已配置主程序的Jar包

java -jar ./target/common1.jar
java -jar ./target/common2.jar
java -jar ./target/common3.jar

e) 运行一个未配置主程序的Jar包,通过命令指定运行的主程序
java -classpath "./target/common.jar" Simple
java -classpath "./target/common.jar" AppLogger
java -classpath "./target/common.jar" com.pphh.demo.AppPkg

5. 参考文献

  1. Java 9 SE技术文档:Javac工具命令
  2. Java 9 SE技术文档:Jar工具命令
  3. Java 9 SE技术文档:Java工具命令
  4. Java 7 SE技术文档:Javac工具命令
  5. Java 7 SE技术文档:Jar工具命令
  6. Java 7 SE技术文档:Java工具命令

永远的民国风华-林徽因

年轻时林徽因

最近读了孟斜阳著的一本书,《一生盛放如莲花:林徽因传》,书中对林徽因的一生有着详细的记述,为爱痴狂的徐志摩,愿白首得一人心的梁思成,柏拉图式爱情的金岳霖,都分别单独一个卷章,记录了那个时代围绕着民国风华人物林徽因发生的故事。

林徽因

林徽因的诗,她的直率纯真,她的才华美貌,让所有接触过她的人都发出赞叹,也是留给我们后人对那个时代最值得去回忆的一个符号。

林徽因在1904年出生在一个名门之家,父亲林长民曾留学日本早稻田大学,在清末民国初期,社会动荡,思想活跃,林长民带着开明的才学和热血的激情进入政坛,直到后来在反奉反内战、征讨张作霖中,中流弹而失去了自己的生命。父亲对林徽因的影响是一生的,同时父亲对林徽因也寄予了深厚的期望,他曾说到,“作为一名天才女儿的父亲,不是容易享的福”,这种福不仅仅是幸运,更多的是责任。在林徽因14岁的时候,林长民带着她游历欧洲英国,徽因因此接触到了国外的进步,了解了外面的世界,练就了纯正流利的英语,慢慢深得中西方艺术文化真谛。也就是这个时候,她见到了徐志摩。

徐志摩

林徽因,对于徐志摩来说,是诗情的开始,也是诗情的结束。在伦敦剑河的桥边,两人一路相伴,畅想阔论,徐志摩从第一眼看见徽因开始,便知道自己一直寻找的灵魂伴侣就在眼前,于是抛妻离家,为了爱情,他不顾一切的去追求自己理想的她,每一首诗,每一行字,都倾注他对爱的渴望、期待、痛苦、坚持和执着,直到再一次飞往心中的那个她时,带着悠悠的思念,只为再一次和徽因相遇,却永远消失在天边。

1931年,徐志摩在收到林徽因的学术报告邀请,在飞行的途中飞机出事,徐志摩永远地消失在天边的云彩。轻轻的他来了,轻轻的他走了,有人说,徐志摩先生最好的一首诗是他的人生。

徐志摩走后,林徽因让梁思成从出事的地方带回一个飞机残片,挂在房屋床头,一直陪伴她到终点。

梁思成

林徽因和梁思成,始于父辈梁启超和林长民的安排,才子佳人相见很早,对彼此都留下深刻的印象。当林徽因1921年从伦敦回来,两个人便有了媒妁之言,而后1925年父母的安排下,一起赴美学习,而后在1927年行文定礼成婚。

梁思成不善言辞,却不乏幽默感,为人宽容厚重,和林徽因的俏皮可爱形成鲜明的对比,两者取长补短,生活中渐渐相互融合。在事业上,两个人共同选择了建筑,从1930年到1945年,梁思成林徽因夫妇二人共同走了中国的15个省,190多个县,考察测绘了2738处古建筑物,让很多中国古建筑重见天日,获得世界的认识,两人通过这些考察,最后一起破解了中国古书《营造法式》,为中国古代建筑学研究奠基。正是有了这共同的事业,两个人一起学习,一起成长,度过了艰难的战争岁月,一路走来,两个人的爱情愈加深沉圆润。梁思成为拥有徽因而珍惜不已,处处为徽因着想,而徽因为思成的胸怀大度所折服,佳偶天成。

金岳霖

在梁思成和林徽因的生活中,有一个人始终陪伴左右,那就是金岳霖,他终生未娶,把对徽因的爱恋沉在心底。老金在1932年搬到梁家所在胡同后,开始了二十多年的“逐林而居”,每天和梁林生活在同一屋檐下。金老对徽因的爱,发乎情止于礼,体现君子之风。在徽因逝世多年后,有一天,金老郑重其事地邀请了一些至交好友到北京饭店赴宴,没有说任何理由,正当大家在琢磨宴请为何时,金老在开席时站了起来,说:“今天是徽因的生日。”一句话让大家感叹不已。金岳霖对徽因的爱一生未变,后来梁思成和另一女子结婚,重温二人世界,金老对此一声不吭,每年逢徽因忌日,他总是要去拜访徽因墓,献上自己的一束花。在金老的晚年,有人请他为徽因诗集出版说一些话,他想了很久,没有啃声,最后他一字一顿地、毫无含糊地说:“我所有的话,都应该同她自己说,我不能说,我没有机会同她说的话,我不愿意说,也不愿意有这种话。”说完便默。

金岳霖独身一人,直到自己生命尽头,把自己对徽因的爱恋带到了最后。值得大家称赞的是,金岳霖对徽因的孩子视如己出,徽因的孩子也把金老当成自己的家人,照顾他到最后老去。

随着金老的离去,民国那些年围绕着林徽因的故事渐渐落下了帷幕,时间带走了那个时代对爱情的表达,留下了人们对那个时代风华的记忆。

参考资料

  • 《一生盛放如莲花:林徽因传》,孟斜阳著
  • 百度百科:林徽因

2017上海的秋

外面的暖阳照着大地,时令已过大雪,秋风吹面,没有北方那么冷的刺骨,却让人有些清爽,有着冬衣裹身,走在落叶铺着的地面,有一些怀念的感觉。

现在路边的银杏树最是好看的时候,叶子金灿灿的,在繁树绿草中最是亮眼,走着走着也会停住脚步,上下左右打量着这美景,或许这就是一年秋季最美的时候,自己忍不住地也会多看几眼。

公司搬到了丹桂路这边,最喜欢的便是路边沿河的一大片绿地,每到中午河两岸的行人漫步,三三两两,尽享阳光和美景。我一有空便加入这些行人景色之中,走在河岸上,这个时候我可以打开手机,和家人电话、视频聊天,嘘寒问暖,商量着一天的事情。每到这个时候,也是一天之中心情最为放松大好的时候。