22

I am compiling multiple files in a directory (javac *.java) but I have a problem when I try to do this.

I get compile errors saying that javac cannot find a symbol of an object.

I have multiple packages that contain Java files that are needed to run the main program. But it seems that trying to compile these one by one won't work. It runs fine in my IDE but I'm interested in learning how it's done via command prompt.

The main program is in the drivers folder. I have tried compiling the files in order of dependency but that didn't work out.

this is a screenshot of the folders

informatik01
  • 16,038
  • 10
  • 74
  • 104
OKGimmeMoney
  • 575
  • 2
  • 7
  • 19
  • If in `argfile` you have the list of all the files to compile, you can run [`javac @argfile`](http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javac.html#commandlineargfile). If you are using other libs, you have to add the classpath them. – Alberto Jun 19 '13 at 14:51
  • When I do something like editing the class path name (in this instance) where should I do it and how? I have heard about that being done inside the manifest file, however I know that it can be done in the OS settings as well. – OKGimmeMoney Jun 19 '13 at 20:49
  • You can add classpath dependency through the `-classpath` option like: `javac -classpath \examples;\lib\Banners.jar \examples\greetings\Hi.java`. Look at http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javac.html and http://docs.oracle.com/javase/7/docs/technotes/tools/windows/classpath.html. – Alberto Jul 23 '13 at 08:14

3 Answers3

28

Javac documentation provides all the necessary information. However, it might be useful to use Ant or Maven for command line builds.

This page provides a good example of using first javac and then Ant for building a simple project.


Here is an example project and how can it be compiled with javac.

The tree structure of the project is this:

   .
    ├── build
    └── src
        ├── attacks
        ├── drivers
        │   └── Driver.java
        └── exceptions
            └── MyException.java

There are two special directories -- build for containing compiled classes and src to contain source files (could be in different subdirectories -- packages).

The following command compiles the whole project and puts the result into the build directory.

javac -sourcepath src -d build src/**/*.java

The -sourcepath src specifies directory src as the place where all the source can be found by the compiler. The -d build options tells the compiler where to place the compiled files.

Option src/**/*.java tells the compiler what files to actually compile. In this specific case it tells javac to look two levels down and pick all *.java at that level.

If there are *.java files at different levels than a list of files needs to be specified. For this, one could create such listing as an external file and pass this files as in input option for javac.

Here is how this could be done under Linux/Unix:

find -name "*.java" > source.txt

The above command creates file source.txt that contains full paths for the found *.java files. For this example it contains:

./src/drivers/Driver.java
./src/exceptions/MyException.java

In order to compile the project with the list of source files flushed into source.txt, the following command can be used:

javac -d build @source.txt

Please note that @source.txt specified at the end that tells the compiler where to look for a list of source files. Please also note that the -sourcepath option can be omitted.

Here is how the directory structure changed after running the above command.

.
├── build
│   ├── drivers
│   │   └── Driver.class
│   └── exceptions
│       └── MyException.class
└── src
    ├── attacks
    ├── drivers
    │   └── Driver.java
    └── exceptions
        └── MyException.java

As can be observed the build directory now contains the compiled class files in respective packages.

And, if you'd like to run it, assuming, for example, that Driver has method main, the following command executes the program.

java -cp .:build:**/*.class drivers.Driver

Please note that file separator : (colon) is used under Unix, for Windows change it to ; (semicolon).

01es
  • 5,362
  • 1
  • 31
  • 40
  • I'll look over the documentation. A different problem I am having is that when I do get the .jar file it won't run like it runs in the IDE. The icon just blinks and then does nothing. – OKGimmeMoney Jun 17 '13 at 05:19
  • @CanIHaveSomeChange It is best if your register this other problem as a different question. Have you compiled the project successfully? – 01es Jun 18 '13 at 13:48
  • I have not gotten the program to compile. What's happening is in the original post. – OKGimmeMoney Jun 19 '13 at 00:02
  • @CanIHaveSomeChange Please extend your question then with the project structure, including the java file names. This way it would be possible to provide you with an exact answer. – 01es Jun 19 '13 at 06:17
  • Your latest post is helpful. The command where you say: "javac -sourcepath src -d build src/**/*.java" What is that saying in English from left to right? Specifically, it would be helpful to me to know what the dashes and spaces mean to the command line when the command is executed. – OKGimmeMoney Jun 19 '13 at 23:14
  • @CanIHaveSomeChange Please have a look at the expanded answer. – 01es Jun 20 '13 at 13:59
  • 1
    No need to gather the java file names in another file. Just use this following example: `javac -d compiled $(find src -name *.java)`. Source: http://stackoverflow.com/a/3512668/435605 – AlikElzin-kilaka May 07 '15 at 18:17
3

I am compiling multiple files in a directory (javac *.java)

Wrong already. That will only work correctly if the Java classes aren't in packages. The correct way to do this is as follows, where src is the name of the directory at which all your package directories are rooted:

cd src
javac package1/package2/*.java
javac package3/package4/package5/*.java

etc for whatever your package/directory layout is. Each javac command line will compile all the files in the named directory and all the .java files in other packages/directories that it depends on that aren't already compiled or that are out of date.

See the Tool documentation for javac.

user207421
  • 305,947
  • 44
  • 307
  • 483
2

two options:

1) Use the command line to specify all files to compile

2) Create a file with all the filenames (output from find, perhaps), and run javac @argfile

Niels Bech Nielsen
  • 4,777
  • 1
  • 21
  • 44
  • You mean throw all the java files into one directory? I will try this as an experiment, but it's not an end-solution. – OKGimmeMoney Jun 17 '13 at 05:24
  • No, he didn't say anything about putting all the java files into one directory. Don't do that, it can't work. – user207421 Jun 17 '13 at 07:23
  • I'm not sure if I am doing this right but I got this error after trying to run the program after your first step: OK, I tried this and now I am getting a run-time error that says "java.lang.NoClassDefFoundError: ProgramName I do not know how to perform that second step; I read through the Java Documentation recommended in this thread by someone else and I don't understand how to use it. – OKGimmeMoney Jun 17 '13 at 07:36
  • NoClassDefFoundError comes from putting all the .java files in the same directory, which nobody has told you to do. – user207421 Jun 17 '13 at 08:50
  • I got the NoClassDefFoundError with my original setup as well. – OKGimmeMoney Jun 18 '13 at 07:53
  • On unix use 'find src/main/java/ -type f -name \*.java > argfile' on windows use 'dir *.java /s /b > argfile', and then use 'javac @argfile' – Niels Bech Nielsen Jun 18 '13 at 11:44
  • I am confused about the /s /b and argfile parts. I'm running windows. I typed in what you said, replacing the asterisk with the name of the file, then copying the rest exactly as you wrote it. The first command made a file called "argfile" in the same directory as the file and Eclipse opened up. The second command yielded this in Cmd "javac: no source files Usage: javac use -help for a list of possible options" – OKGimmeMoney Jun 19 '13 at 00:10
  • Ok, the argfile should contain a list of all the sourcefiles full with paths?.. Good, the javac @argfile would call the compiler and ask to compile all the files specified in argfile. – Niels Bech Nielsen Jun 19 '13 at 06:48