21

How to compile all java files in all subfolders on Unix, using javac?

Danubian Sailor
  • 21,505
  • 37
  • 137
  • 211
aneuryzm
  • 55,858
  • 96
  • 259
  • 471

6 Answers6

29

On Windows...

Create a batch file:

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

...then execute it in the top-level source folder.

On Linux...

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

Both answers taken from this thread...

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

But as others suggested, a build tool would probably prove helpful.

veganaiZe
  • 491
  • 5
  • 12
Brandon Frohbieter
  • 15,944
  • 3
  • 33
  • 60
  • thanks. I get this error message though: javac: invalid flag: ./lucene/org/apache/lucene/.svn/prop-base/LucenePackage.java.svn-base – aneuryzm Mar 04 '11 at 14:28
  • oops, seems that file has a .java extension and you don't want to compile it, does it work with grep --include=.java? did it still compile your other files? – Brandon Frohbieter Mar 04 '11 at 14:32
  • for /r %a in (*.java) do (jikes.exe -d bin\ -cp jre6\lib\rt.jar;WEB-INF\lib\\*.jar "%a") – diyism Nov 13 '11 at 07:27
  • for /r %a in (*.java) do (java -jar ecj.jar -d bin\ -cp jre6\lib\rt.jar;WEB-INF\lib\*.jar "%a") – diyism Nov 13 '11 at 12:47
  • On win10, got this error: `%%a was unexpected at this time.` – Lei Yang Dec 14 '17 at 12:17
17

Use a build tool such as Ant or Maven. Both lets you manage dependencies in a much better way than can be accomplished using e.g. the find UNIX tool. Both And and Maven also lets you define custom tasks to be performed in addition to compilation. Maven furthermore comes with conventions for managing external dependencies in remote repositories, as well as conventions for running unit tests and features that support continuous integration.

Even if you just need to compile your source files once in a while, you'll probably find that setting up a simple Ant build.xml file can be a big time saver in the end.

Finally, most of the popular IDE and code editor applications has some kind of integration with Ant build scripts, so you can run all the Ant tasks from within the editor. NetBeans, Eclipse, IDEA and more also has built-in support for Maven.

Read this first, if you're new to Ant. Below is the example build file from the link:

<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>

Once you're familiar with Ant, you'll find it easier to move to Maven.

Kim Burgaard
  • 3,368
  • 16
  • 11
  • 4
    Shouldn't the right answer be: "you do it like this... but Ant/Maven will work out better for you"? Someone who's actually trying to grasp how to use javac (what the question is aimed at) will not find an answer in this. – dmg_ Jun 25 '16 at 17:58
9

I don't know if it is the best way, but this should work :

find . -name "*.java" | xargs javac
krtek
  • 25,218
  • 5
  • 53
  • 79
  • uhm, it doesn't work. Is maybe because find command works differently on mac ? (-name flag doesn't exist) – aneuryzm Mar 04 '11 at 14:27
  • 1
    according to http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man1/find.1.html the -name option exists. – krtek Mar 04 '11 at 14:29
  • Even if -name is supported, it won't work if a .java file exists in the current folder, since the shell will expand the wildcard. Use quotes (aka find -name "\*.java"). – Axel Mar 04 '11 at 14:31
  • I modified the answer to add the quotes and the path to use. It should work on Mac OS X this time. And it works on Debian without the quotes : $ find . -name *.java ---> ./test.java – krtek Mar 04 '11 at 14:32
  • Placing java files in 'default' package is anyway discouraged. You can't import that classes from any other package. – Danubian Sailor Dec 16 '13 at 10:40
2

Use Ant to write a script to compile as many source folders as you want.

Andrey Adamovich
  • 19,123
  • 13
  • 83
  • 125
1

Use Maven (as a more modern alternative to Ant).

Use an IDE, like Eclipse (all IDEs I know will happily compile multiple source folders for you)

Sean Patrick Floyd
  • 274,607
  • 58
  • 445
  • 566
0

Another (less flexible) way, if you know how much folder levels there are:

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

Depending on your shell, you may have to set it to expanding non-matching patterns to nothing, in bash with shopt -s nullglob. For example, I'm using the following shell function to find text in my java files:

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

jgrep String

But really, use an build tool, as the others said.

Paŭlo Ebermann
  • 68,531
  • 18
  • 138
  • 203