Class not being compiled automatically

Javac was successfully re-compiling all my classes, except one, a class I had called "Box.java". Javac would compile it if specifically asked: javac Box.java, but not as part of a re-compile of the whole project.

  1. Am I right in thinking that this is because there is, it turns out, a class called "Box" (part of Swing I believe, and I am using Swing generally elsewhere)? The problem seems to have gone away by renaming my class (and associated methods etc.) "DecisionBox.java".

  2. If that's right, what's the best way of avoiding in future. I can find a list of Java reserved words fairly easily, but reserved classes....? Just search the JavaDocs? Or would an IDE spot this error?

I only ask because with no error messages it took ages to track down that a class wasn't being recompiled...

Upvotes: 3

Views: 1956

Answers (1)

Jason C
Jason C

Reputation: 40335

It depends a bit on how you are compiling your whole project, and how your other source files use Box.

The Java compiler will automatically compile dependencies. It's not a problem that you have a class named Box that is the same name as javax.swing.Box, because the package names are used to differentiate.

However, it's possible, for example, that none of the other classes you are compiling are referring to your Box. For example, if you import javax.swing.* everywhere, and then just use Box, the class could very well be using javax.swing.Box. If the compiler can always resolve Box to javax.swing.Box, it has no reason to compile your Box, because as far as its concerned, you never use it.

If you are using the default package (i.e. no package) for your source files this can encourage potential confusion even more. You want to stay organized and be as explicit as possible about packages. Using the default package means you can't explicitly qualify your own class's names.

To be sure, make sure you are importing specific classes from packages instead of javax.swing.*, and if you need to use both your Box and javax.swing.Box in the same source file, explicitly specify the package names.

In other words, it sounds like the compiler is, at some point, not seeing that your Box is the one your classes are using -- and explicit imports and use of fully qualified package names can eliminate that confusion.

One experiment you can try is to delete all your compiled .class files, then recompile your project. If Box.java is never compiled, that is a hint that you may not actually be using it even though you think you are.

Fundamentally, if anything, this is a good case for not using wildcard package imports. By always explicitly importing the classes you are using, you significantly reduce the chance of the compiler making incorrect assumptions about your intentions. This (and, to a lesser extent, not using the default package) is the best way to avoid this situation in the future.

Update, based on new info in comments: The OP has a relation graph like:

 FirstClass
     Topic
         Boat
         DecisionBox

The reason Boat/DecisionBox don't get recompiled when they are modified is that Topic hasn't changed. So when you recompile FirstClass, it checks Topic. Topic doesn't need recompiled, and so Topic's dependencies aren't checked. If FirstClass referred directly to Boat (even e.g. Topic.getBoat()) then Boat would be recompiled. It's a shortcoming of javac's very basic dependency walking. Either delete all .class before recompiling, or you could use some other build system like ant (where you can specify dependencies) or your IDE's internal system (e.g. most IDE's will magically take care of this for you, although it is certainly nice to learn the command line interface, in practice you rarely use it without a supplementary build system).


Another possibility, by the way, although this is far less likely, is some incorrect timestamp on your Box.java or compiled Box.class that causes the compiler to think it didn't change, and thus doesn't need recompiled. It will only recompile the file if the timestamp on the .java file is newer than the .class file, or the .class doesn't exist.

Upvotes: 2

Related Questions