2006-6-24

尝试以一个例子来说明搭建一个 project 时候的目录构建情况。

 

情况一

下面以一个地图编辑器的例子为例

project mapeditor

父目录是
”project mapeditor”,

.\Image 程序使用到的图片。

.\Maps 程序运行时用户保存的自定义地图。

.\com 主程序 MapEditor.java 将会是用到的 package 的源文件。

.\com\cjren\swing\MyFilter.java

MapEditor.java 主程序源文件,代码中没有 ”package” 语句。

runMapEditor.bat 完成编译和运行所需的所有工作。

 

下面主要看看 runMapEditor.bat 的内容:

@echo off

rem output the date and time

date /T

time /T

echo welcome to my map editor :-)

 

rem make the directory for class files

mkdir .\build\classes

 

rem compile the source files

javac -d .\build\classes MapEditor.java

 

rem run the application,

rem but you must avoid this: java.\build\classes\MapEditor,

rem which will be an error

java -cp .\build\classes MapEditor

 

rem clean everything in the build folder

rmdir .\build /S /Q

 

pause

 

从上面的具体代码中可以看出在编译和运行的时候,所有的 class 文件都回被放在 .\build\classes 这个文件夹中,这个文件夹是动态生成并且最后会被清楚掉的。

 

这里有三个值得注意的地方。

一,通过 ” javac -d .\build\classes MapEditor.java” ,不单只是 MapEditor.java 所定义的 class 都被放于 .\build\classes 中,甚至连 .\com MyFilter.java 所对应的 class 也都在 .\build\classes\com\cjren\swing 中,而 com 包在 .\bulid\classes 下是自动被准确生成的。也就是说所有的 .class 文件都被放在 .\bulid\classes 文件夹中了。

二,当使用 ”java -cp .\build\classes MapEditor” 来运行程序的时候,并没有因为 Image 文件夹不在 .\build\classes 而出错。这说明了 .java 文件中的代码已经决定了它所使用到的 Image 文件夹的位置,这个位置是相对于 .java 文件所在的位置来说的,而不是 .class

三,我尝试了在 d 盘下新建了一个 a 目录,然后把

javac -d .\build\classes MapEditor.java

java -cp .\build\classes MapEditor

换成

javac -d d:\a MapEditor.java

java -cp d:\a MapEditor

之后,其他 ”project mapeditor” 下的所有东西都没有改变,程序依然成功执行。这就进一步证明了 .java 文件中的代码决定了所有其他目录或文件元素的相对位置,这个位置以 .java 文件所在的目录为标准。而与 .class 文件的路径无关。但是:别混淆了 A.class 它所使用到的包的 .class 的路径是以 A.class 文件的路径为标准的!!!这就与上面 MapEditor.class 也和(必须和) com 包同处于 bulid\classes 目录下没有矛盾。

 

情况二

目的是把上面情况一中所有的文件和文件夹都包含在 src 这个文件夹中,而 src 本身就是父目录 project mapeditor2 下的一个文件夹。而且我希望编译时候生成的 build 文件夹和 src 文件夹的关系是:

\project mapeditor2\src

\project mapeditor2\build



src
文件夹的内容如下:

pj2-src
注意批处理文件
runMapEditor.bat src 文件夹下,而且在此情况下, runMapEditor.bat 的内容将有所变化:

@echo off

rem output the date and time

date /T

time /T

echo welcome to my map editor :-)

 

rem make the directory for class files

mkdir ..\build\classes

 

rem compile the source files

javac -d ..\build\classes MapEditor.java

 

rem run the application,

rem but you must avoid this: java.\build\classes\MapEditor,

rem which will be an error

java -cp ..\build\classes MapEditor

 

rem clean everything in the build folder

rmdir ..\build /S /Q

 

pause

 

情况一和情况二的差别不大,只是源代码文件多一层的文件夹的包裹。而且最大的共同点是 runMapEditor.bat 和源代码文件在同一个文件夹下。

 

情况三

尝试在情况二的基础上把 runMapEditor.bat 提到和 src 以及 build 相同的父目录下。假设父目录是 project mapeditor3 ,则:

pj3
现在
runMapEditor.bat 的内容是:

@echo off

rem output the date and time

date /T

time /T

echo welcome to my map editor :-)

 

rem make the directory for class files

mkdir .\build\classes

 

rem go into the src directory

cd src

 

rem compile the source files

javac -d ..\build\classes MapEditor.java

 

rem run the application,

rem but you must avoid this: java.\build\classes\MapEditor,

rem which will be an error

java -cp ..\build\classes MapEditor

 

rem clean everything in the build folder

rmdir ..\build /S /Q

 

pause

 

在尝试工程当中,发现以下的做法将找不到 Image 文件夹:

cd src

javac -d ..\build\classes MapEditor.java

cd ..

java -cp .\build\classes MapEditor

这种修改所造成的区别是运行 ”java” 命令的位置不同了。可以猜想是需要在 src 文件夹内运行 java 命令,而 src 文件夹中含有所有程序所需的代码和 image 素材。

 

下面提供一个稍微不同的批处理文件, runMapEditor2.bat ,它也同样处于 project mapeditor3 这个父目录下:

pj3-

runMapEditor2.bat
的内容如下:

@echo off

mkdir d:\a

cd src

javac -d d:\a MapEditor.java

java -cp d:\a MapEditor

rmdir d:\a /S /Q

pause

这个修改过的例子把 class 文件都移到较远的地方 (d:\a) ,但是还可以成功运行。小结一下它能成功运行的特点:

一, src 文件夹中已经包含了所有的元素,包括所需的外部 package 代码,包括 image 文件夹。这些元素都必须使得主程序 .java 能成功的编译。

二,运行 ”java” 命令都在 src 这个目录下。也就是说都在和代码处在相同的文件路径下,而不是其他任何路径。

 

情况一都三的小结

基本满足了在 windows 系统下开发小项目的需求,我在这三个尝试的例子中主程序 MapEditor.java 都没有含有 ”package main” 这类的打包语句。