2006-6-24
尝试以一个例子来说明搭建一个 project 时候的目录构建情况。
情况一
下面以一个地图编辑器的例子为例
父目录是 ”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 文件夹的内容如下:
注意批处理文件 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 ,则:
现在 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 这个父目录下:
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” 这类的打包语句。