“在这个世界上有两种人:懂二进制的和不懂二进制的。”
即使您认为这个笑话很糟糕,您可能也会同意它的说法。传统上,世界上主要有两大阵营的开发人员:使用集成开发环境 (IDE) 的开发人员,和坚持使用诸如 VI 和 Emacs 之类的编辑器并利用从 Linux shell 调用的 make 文件进行编译的开发人员。两种方式都没什么错
(尽管对此有持续的激烈争论);它们都有它们自己的优点。
然而,您可能已注意到,现在又出现了第三种观点:一种混合的解决方案,:将 IDE 用于大部分开发工作,而将 Ant 用于团队进行“正式”编译。这种模式是现在我在 Oracle 和其它公司内部的开发团队中看到的最常见的一种模式。
在第 1 部分中,我们讨论了在 Linux 上创建 Java 应用程序时显而易见的最初步骤:安装。在这一部分中,我们重点讲述创建 Java 应用程序的命令行方法。
使用 IDE 或不用 IDE 这是问题的所在
在我们详细展开之前,回顾一下我所描述的这些方法的一些优缺点是很重要的:
- IDE 的优点
- 简化的安装
- 编程工具
- 无需使用 shell
- 集成的编译器
- 集成的调试器
- 众多其它的向导和编码增强
- IDE 的缺点
- 不一定始终能用于自动编译
- 对开发人员屏蔽了 shell
- 可能将事物的工作方式隐藏在表面之下。
注意如果您使用混合的方法,IDE 的主要缺点 — 缺少自动编译支持 — 将得到减轻。Ant 在这里将起到重要的作用。
使用 VI 和 Emacs
VI 和 Emacs 是 Linux 和 UNIX 上(可能也是其它平台上)的两个最流行的编辑器。您使用哪一个编辑器是个人偏好的问题;每一个都可胜任作为文本编辑器。如果您已经熟悉了其中的某个编辑器,请放心地跳过一两部分内容。
VI。VI 最初由 Bill Joy 在 20 世纪七十年代后期为 BSD 编写。它也被 AT&T 选中用于 System V UNIX ,而现在几乎包含在所有的 Linux 和 UNIX 版本中。如果您正在使用计算机,很可能您也将在其中找到 VI。
VI 不同于大多数现代编辑器的地方是,它区分了命令模式和插入模式。在 VI 中,命令模式是执行命令(如移动光标、复制文本、粘贴文本和删除行),插入模式是键入文本并插入到文件中。这种差异一开始可能容易让人混淆,但一旦您习惯了它,它将很有意义,允许一些强大的命令 — 例如 "d10j" 删除文件接下来的 10 行。
要启动 VI 来编辑一个文件,您通将使用 vi filename,其中 filename 是要编辑的文件的名称。您将默认在命令模式下启动。当处于插入模式时,按下 Escape 键将使您切换回命令模式。
在 http://www.vim.org 上提供了许多 VI 教程,以及关于改进的 VI (VIM) — 在大多数 Linux 版本中包含的 VI — 的文档。
下面对命令模式中的众多命令简略地列举一二:
| Key |
命令说明 |
| h |
将光标向左移动一个位置 |
| j |
将光标向下移动一个位置 |
| k |
将光标向上移动一个位置 |
| l |
将光标向右移动一个位置 |
| w |
将光标向右移动一个字 |
| b |
将光标向左移动一个字 |
| i |
切换到插入模式并开始在光标位置插入文本 |
| a |
切换到插入模式并开始在光标位置添加文本 |
| G 或 0G |
将光标移动到文件的末尾 |
| 1G |
将光标移动到文件的开头 |
| :w |
写/保存文件 |
| :q |
退出 VI |
Emacs。Emacs (Editor MACroS 的缩写) 在 1976 年作为用于编辑器 Text Editor and Corrector (TECO) 的一组宏而出现。不像 VI 而是像大多数现代编辑器一样,Emacs 没有区分命令模式和插入模式。Emacs 称为“显示”编辑器,因为您在显示屏上看到文本被可视化地编辑。下面是一个例子:
File Edit Options Buffers Tools Help
This is a new file
-uuu:**-F1 test (Fundamental)--L1--All----------------------------
|
-uuu:**F1 test... 行称为模式行。模式行显示关于 Emacs 的当前模式、在当前缓冲区中打开的文件的名称、光标的行或列位置的信息和各种其它的信息位。模式行下面一行称为回显行。当您执行一条命令时(如保存文件),它将在那里出现。
Emacs 对许多人来说都很直观,因为您可以使用光标键在显示屏上到处移动。不过,它的键盘输入和典型的 Windows 编辑器的键盘输入有所不同。下面是一个简短的命令列表;在这些示例中,"C" 代表 control,而 "M" 代表 Meta 或 Alt。因此,"C-a" 代表“按下 'a' 键,同时按住 Control 键,而 "M-a" 代表“按下 'a' 键,同时按住 Meta 或 Alt 键。”
(注意,虽然一些键盘有 Meta 键,但在大多数 Linux 计算机上,我们使用 Alt 键。)
| Key |
命令说明 |
| C-x C-s |
保存当前的缓冲区 |
| C-x C-c |
退出 Emacs |
| C-a |
将光标移动到当前行的开头 |
| C-e |
将光标移动到当前行的末尾 |
| C-v |
向前翻一页(和 Page Down 一样) |
| C-b |
向后翻一页(和 Page Up 一样) |
| C-d |
删除光标下的字符 |
| M-d |
删除光标下的字 |
| C-k |
从光标位置删除到文件末尾 |
| C-x u |
撤销上一次修改 |
注:
C-x 代表 Control-X
M-X 代表 Alt-X
Java 命令
正如第 1 部分中讨论的那样,在我们的 shell 的 PATH 中应该已有几个命令可供使用了。下面是它们的一个简略列表:
| 命令 |
命令说明 |
| java |
用来调用 Java 应用程序的 Java 命令。您可以直接使用语法 java some.class.file.Name 来启动一个 .class 文件,或以 java -jar jarfilename.jar |
| javac |
Java 编译器,如为 C 开发人员提供的 cc 或 gcc。此命令的语法是 javac [arguments] sourcefile.java。 |
| jar |
Java Archiver,如 zip 或 tar。此命令语法与 TAR — UNIX 上的原始 Tape ARchiver 实用程序 — 极其相似。由 JAR 产生的文件与标准的 zip 实用工具兼容。 |
| ant |
Ant 是一个与 GNU Make 类似的开放源代码的编译系统。虽然在您的 PATH ant,但它将在以后提供。
|
获取并安装 Ant
Ant 是 Apache 软件基础的一个项目。它由 James Duncan Davidson 编写,用来编译原始的 Tomcat Servlet Container。Ant 与 make 类似,不过,它使用 XML 作为语法,并使用 Java (而不是 shell 脚本和其它平台专用的工具)进行了扩展。
安装 Ant 是一个简单的分为两步的过程:
1. 下载一个二进制版本,并把它解压缩到 /usr/local/ant 中。下面是使用 root 帐户执行这些步骤的一个例子;它假定已经将 Apache-Ant 二进制版本下载到了 root 用户的主目录中(通常为 /root)。
# cd /usr/local/
# tar jxf $HOME/apache-ant-1.5.4-bin.tar.bz2
# ln -s /usr/local/apache-ant-1.5.4/ ant
2. 编辑 shell 脚本来设置 ANT_HOME,并确保在您的 PATH 提供了 ant shell 脚本。
下面是位于 /etc/profile.d 中的 Java 脚本的新版本,它们是在上一部分中被创建的。注意发生的变化是:
- ANT_HOME 现在设为/usr/local/ant
- PATH 已更新包含了${ANT_HOME}/bin
注:当您看到类似 $HOME 的东西时,您已找到了 HOME 环境变量 — Linux 上的标准变量之一。如果您想要看看它的值是什么(换句话说,它代表什么),那么您可以从控制台使用 echo $HOME 命令。下面是一个例子:
# echo $HOME
/home/rcleveng
java.sh
# /etc/profile.d/java.sh - Sets Java Environment
if [ -z "$JAVA_HOME" ]; then
if [ -e /etc/javaversion ]; then
javaver=`cat /etc/javaversion | head -1`
fi
if [ -z $javaver ]; then
jdkpath=`ls -1 /usr/java/ | grep "$javaver" | head -1`
if [ "X$jdkpath" == "X" ]; then
jdkpath=`ls -1 /usr/java/ | head -1`
fi
} else
jdkpath=`ls -1 /usr/java/ | head -1`
fi
export JAVA_HOME=/usr/java/$jdkpath
export ANT_HOME=/usr/local/ant
export PATH=${PATH}:${JAVA_HOME}/bin:${ANT_HOME}/bin
fi
java.csh
# /etc/profile.d/java.csh - Sets Java Environment
if ( !JAVA_HOME ) then
if ( -e /etc/javaversion ) then
set javaver = `cat /etc/javaversion | head -1 `
endif if ( javaver ) then
set jdkpath = `ls -1 /usr/java/ | grep '$javaver' | head -1`
if ( $jdkpath == '' ) then
set jdkpath = `ls -1 /usr/java/ | head -1`
endif
} else
set jdkpath = `ls -1 /usr/java/ | head -1`
endif
setenv JAVA_HOME /usr/java/$jdkpath
setenv ANT_HOME /usr/local/ant
setenv PATH ${PATH}:${JAVA_HOME}/bin:{$ANT_HOME}/bin
endif
项目布局
项目布局可能根据项目类型而变化。例如,一个 J2EE 项目将可能拥有与您的标准 Java 桌面应用程序不同的布局。下面是一个 Java 桌面应用程序的一个典型布局。该应用程序设计为置于主目录下。在这种布局下,有为应用程序源代码、已编译的 .class 文件、项目的 javadoc、项目使用的外部资料库提供的子目录,和为已部署的 (jar'ed) Java 应用程序(当它准备好进行测试时)提供的位置。
Project Home Directory
+ -- build.xml (Ant build file, if you are not using ant, ignore)
+ -- build.properties (Properties used by the Ant build file, optional)
+ -- LICENSE (If you require the license, here is a good place for it)
+ -- src/ (Java source and resources)
+ -- org/...
+ -- META-INF/
+ -- META-INF/Manifest.mf (Manifest file for the JAR you will create later)
+ -- classes/ (Compiled .class files)
+ -- org/...
+ -- javadoc/ (Javadoc)
|
+ index.html
+ org/...
+ -- deploy/ (This is where the built application will reside)
+ -- lib/ (External Depenencies will go here)
|
创建 Hello World Java 源代码
在您能够启动您的项目之前,您必须确定将它置于何处。在下面的示例中,我将使用 $HOME/projects/helloworld 作为我的项目的位置。下面是设置目录结构的步骤列表:
# mkdir $HOME/projects
# mkdir $HOME/projects
# mkdir $HOME/projects/helloworld
# mkdir $HOME/projects/helloworld/classes
# mkdir $HOME/projects/helloworld/src/otn
# cd $HOME/projects/helloworld/src/otn
# vi Main.java
注意:按下 'i',将 VI 置于插入模式。同样,您可以使用任何您想用的编辑器;VI 在这里只是作为一个例子使用。
package otn;
public class Main
{
public static void main(String args[]) )
{
System.out.println( "Hello World" );
}
}
按下 ESCAPE 键,随后键入 ":wq" 来保存文件。然后,可以使用以下命令来检验目录结构:
# cd $HOME/projects
# find .-print
.
./helloworld
./helloworld/src
./helloworld/src/otn
./helloworld/src/otn/Main.java
./helloworld/classes
从 Shell 进行编译
我们使用 Java 编译器 (javac) 来编译 Java 源代码。如果您熟悉 gcc 或大多数 C 编译器,则对 javac 有似曾相识的感觉。我们必须告诉 javac 的是:
- 源代码路径;可找到 java 文件的位置
- 放置已生成的 .class 文件的位置
- javac 需要编译哪一个 .java 文件
下面是用来编译 Main.java 文件的 javac 命令行:
# cd $HOME/projects/helloworld
# javac -sourcepath src -d classes src/otn/Main.java
现在您可以用下方式来检验已创建的文件:
# cd $HOME/projects/helloworld/classes
# find .-name *.class -print
./otn/Main.class
创建您的第一个 Ant 编译文件
我们将创建一个 Ant 编译文件 (build.xml),它有以下属性:
- 它有 1 个名为"make" 的目标,该目标是默认的目标。
- 它将在 otn/ 子目录下的所有 java 文件上调用 javac 编译器。
- 它将保留一个时间戳记,并显示花费的时间。
在 $HOME/projects/helloworld 中创建一个名为 build.xml 的文件,它有以下内容:
<xml version = '1.0'>
<project name = "OTN" default = "make" basedir = ".">
<target name = "make">
<tstamp />
<javac srcdir="src/" destdir = "classes/">
<include name="otn/**"/>
</javac>
</target>
</project>
下面是调用 Ant 命令来编译我们的示例的命令和输出:
# ant
Buildfile: build.xml
make:
[javac] Compiling 1 source file to /home/rcleveng/projects/helloworld/classes
BUILD SUCCESSFUL
Total time:3 seconds
您刚刚创建了一个简单的 Java 应用程序。