Java: How can I compile an entire directory structure of code ?

162,846

Solution 1

You have to know all the directories, or be able to use wildcard ..

javac dir1/*.java dir2/*.java dir3/dir4/*.java dir3/dir5/*.java dir6/*src/*.java

Solution 2

With Bash 4+, you can just enable globstar

shopt -s globstar

and then do

javac **/*.java

Solution 3

If all you want to do is run your main class (without compiling the .java files on which the main class doesn't depend), then you can do the following:

cd <root-package-directory>
javac <complete-path-to-main-class>

or

javac -cp <root-package-directory> <complete-path-to-main-class>

javac would automatically resolve all the dependencies and compile all the dependencies as well.

Solution 4

I would take Jon's suggestion and use Ant, since this is a pretty complex task.

However, if you are determined to get it all in one line in the Terminal, on Linux you could use the find command. But I don't recommend this at all, since there's no guarantee that, say, Foo.java will be compiled after Bar.java, even though Foo uses Bar. An example would be:

find . -type f -name "*.java" -exec javac {} \;

If all of your classes haven't been compiled yet, if there's one main harness or driver class (basically the one containing your main method), compiling that main class individually should compile most of project, even if they are in different folders, since Javac will try to the best of its abilities to resolve dependency issues.

Solution 5

Following is the method I found:

1) Make a list of files with relative paths in a file (say FilesList.txt) as follows (either space separated or line separated):

foo/AccessTestInterface.java
foo/goo/AccessTestInterfaceImpl.java

2) Use the command:

javac @FilesList.txt -d classes

This will compile all the files and put the class files inside classes directory.

Now easy way to create FilesList.txt is this: Go to your source root directory.

dir *.java /s /b > FilesList.txt

But, this will populate absolute path. Using a text editor "Replace All" the path up to source directory (include \ in the end) with "" (i.e. empty string) and Save.

Share:
162,846
euphoria83
Author by

euphoria83

Love computers, technology and Apple. Wanna be entrepreneur.

Updated on September 18, 2020

Comments

  • euphoria83
    euphoria83 over 3 years

    The use case is simple. I got the source files that were created using Eclipse. So, there is a deep directory structure, where any Java class could be referring to another Java class in the same, child, sibling or parent folder.

    How do I compile this whole thing from the terminal using javac ?

  • euphoria83
    euphoria83 over 13 years
    unfortunately, this is to be done on a server that doesn't support ant.
  • euphoria83
    euphoria83 over 13 years
    i figured it: just list all the .java files after javac either using their names or wildcards.
  • n611x007
    n611x007 over 11 years
    on windows one can use find_gnu . -type f -name "*.java" | xargs javac once the gnu version of find.exe gets renamed to find_gnu.exe. I got my gnu find.exe from msysgit.
  • Alphaaa
    Alphaaa about 11 years
    This is by far the easiest working solution. Why people don't like it?
  • Ajax
    Ajax almost 11 years
    Probably because its simplicity ignores the fact that many compile jobs for library or support code will not have a main method linking to all required dependencies. It's a good answer, but not one I would ever use in any framework / public codebase.
  • svenwltr
    svenwltr over 10 years
    IMHO, frameworks or any other public projects should use some kind of build management. This kind of compiling, only makes sense on small private projects.
  • DmitrySandalov
    DmitrySandalov over 9 years
    or use zsh with oh-my-zsh :)
  • Matthieu
    Matthieu over 9 years
    Or on pure Windows batch: for /f "usebackq" %f in (``dir /s /b *.java``) do javac %f (use single back-quotes in dir /s /b but I can't find a way to format it properly).
  • coderatchet
    coderatchet over 8 years
    @Ajax but if that is the case, you could also use the -sourcepath . option and then name the main file for the same effect
  • Ajax
    Ajax over 8 years
    Who says there is a main? Who says there isn't four mains? Is every class you want in your output even referenced by main (and not using META-INF/services or other service loading technique). If all you are doing is testing a main, this method is fine, however, it fails to address the complete task of "compile all the java files in a given directory". A proper build system is #1, cli tools like find . -type f -name "*.java" | xargs javac are number 2, and this method only if there is a single main method entry point that encompasses the entire app.
  • lovespring
    lovespring over 8 years
    this is the more "native" way, as javac support a "batch" file
  • Stefan
    Stefan about 8 years
    Or just use javac $(find . -name "*.java").
  • St.Shadow
    St.Shadow almost 8 years
    works, but superslow - javac is called with one file only per call, so if you have a lot of them...
  • aderesh
    aderesh over 7 years
    "dir *.java /s /b > FilesList.txt" approach won't work if a path contains spaces. javac will complain about FilesList.txt
  • AlikElzin-kilaka
    AlikElzin-kilaka over 5 years
    I think the find solution is problematic because it compiles each java class separately, making it very slow.
  • Eenvincible
    Eenvincible over 5 years
    I am having a problem compiling a client source code generated by swagger
  • aderchox
    aderchox over 2 years
    Would ** work as well for being able not to specify the middle directories?