在所有子文件夹中编译Java文件?

23

如何在Unix系统中使用javac编译所有子文件夹中的Java文件?

6个回答

30

在Windows操作系统上...

创建一个批处理文件:

for /r %%a in (.) do (javac %%a\*.java)

然后在顶层源文件夹中执行它。

在Linux上...

javac $(find ./rootdir/* | grep .java)

这两个答案取自于此主题...

http://forums.oracle.com/forums/thread.jspa?threadID=1518437&tstart=15

但正如其他人所建议的,构建工具可能会证明很有用。


谢谢。我得到了以下错误消息:javac:无效的标志:./lucene/org/apache/lucene/.svn/prop-base/LucenePackage.java.svn-base - aneuryzm
哎呀,看起来这个文件扩展名是 .java,你不想编译它,那么它能用 grep --include=.java 命令工作吗?它是否还编译了其他文件? - Brandon Frohbieter
for /r %a in (.java) do (jikes.exe -d bin\ -cp jre6\lib\rt.jar;WEB-INF\lib\.jar "%a") - diyism
1
for /r %a in (*.java) do (java -jar ecj.jar -d bin\ -cp jre6\lib\rt.jar;WEB-INF\lib*.jar "%a") - diyism
在Win10上,出现了这个错误:%%a 在此处不是预期。 - Lei Yang

17
使用构建工具,如 AntMaven。它们都可以比使用UNIX工具例如find更好地管理依赖关系。而且,两者均可定义自定义任务以进行编译之外的其他操作。此外,Maven 还提供了用于管理远程存储库中的外部依赖项以及运行单元测试的约定,并支持连续集成的功能。
即使您只需要偶尔编译源文件,您也可能会发现设置一个简单的 Ant build.xml 文件最终可以节省大量时间。
最后,大多数流行的IDE和代码编辑器应用程序都具有与Ant构建脚本的某种集成,因此您可以从编辑器内运行所有Ant任务。 NetBeansEclipseIDEA等还具有内置的对Maven的支持。
如果您是Ant的新手,请先阅读此文档。下面是链接中的示例构建文件。
<project name="MyProject" default="dist" basedir=".">
    <description>
        simple example build file
    </description>
  <!-- set global properties for this build -->
  <property name="src" location="src"/>
  <property name="build" location="build"/>
  <property name="dist"  location="dist"/>

  <target name="init">
    <!-- Create the time stamp -->
    <tstamp/>
    <!-- Create the build directory structure used by compile -->
    <mkdir dir="${build}"/>
  </target>

  <target name="compile" depends="init"
        description="compile the source " >
    <!-- Compile the java code from ${src} into ${build} -->
    <javac srcdir="${src}" destdir="${build}"/>
  </target>

  <target name="dist" depends="compile"
        description="generate the distribution" >
    <!-- Create the distribution directory -->
    <mkdir dir="${dist}/lib"/>

    <!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
    <jar jarfile="${dist}/lib/MyProject-${DSTAMP}.jar" basedir="${build}"/>
  </target>

  <target name="clean"
        description="clean up" >
    <!-- Delete the ${build} and ${dist} directory trees -->
    <delete dir="${build}"/>
    <delete dir="${dist}"/>
  </target>
</project>

如果你熟悉Ant,那么转换到Maven会更容易。


5
难道正确的答案不应该是:“你可以这样做……但使用Ant/Maven会更好?” 实际上试图理解如何使用javac(问题的关键)的人将无法在这个回答中找到答案。 - dmg_

10

我不知道这是否是最好的方法,但这应该可以工作:

find . -name "*.java" | xargs javac

嗯,它不起作用。可能是因为在 Mac 上 find 命令的工作方式不同?(-name 标志不存在) - aneuryzm
1
根据http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man1/find.1.html的说明,-name选项是存在的。 - krtek
即使支持-name选项,如果当前文件夹中存在一个.java文件,它也无法工作,因为shell会扩展通配符。请使用引号(例如find -name“* .java”)。 - Axel
我修改了答案,添加了引号和路径以供使用。这次应该可以在Mac OS X上运行。而且在Debian上不需要引号:$ find . -name *.java ---> ./test.java - krtek
将Java文件放置在“default”包中是不被鼓励的。您无法从任何其他包中导入这些类。 - Danubian Sailor
1
如果路径中有空格,这段代码将无法正常工作。如果确实存在空格,请使用以下代码:find . -name "*.java" | xargs -I {} javac {} - tedtanner

2
使用Ant编写脚本来编译您想要的许多源文件夹。请参考Ant官方文档

1

如果您知道有多少个文件夹级别,另一种(不太灵活)的方法是:

javac *.java */*.java */*/*.java */*/*/*.java */*/*/*/*.java ...

根据您的shell,您可能需要将其设置为将非匹配模式扩展为空白,在bash中使用shopt -s nullglob。例如,我正在使用以下shell函数在我的java文件中查找文本:

function jgrep ()
{
    (
      shopt -s nullglob
      egrep --color=ALWAYS -n "$@" *.tex *.java */*.java */*/*.java */*/*/*.java */*/*/*/*.java */*/*/*/*/*.java
    )
} 

jgrep String

但是,像其他人所说的那样,真的要使用构建工具。


1

使用Maven(作为Ant的更现代替代品)。

使用一个IDE,比如Eclipse(我知道的所有IDE都可以愉快地为您编译多个源文件夹)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接