Big Moose Saloon
 Search | Java FAQ | Recent Topics Register / Login

# Classpath Related Question

C Halbe
Greenhorn

Joined: Jul 18, 2008
Posts: 20
Hi,

I just find the below question and answer very very confusing:

Question:

Given the default classpath:
/foo

And this directory structure:
foo
|
test
|
xcom
|--A.class
|--B.java

And these two files:

Which allows B.java to compile? (Choose all that apply.)
A. Set the current directory to xcom then invoke
javac B.java
B. Set the current directory to xcom then invoke
javac -classpath . B.java
C. Set the current directory to test then invoke
javac -classpath . xcom/B.java
D. Set the current directory to test then invoke
javac -classpath xcom B.java
E. Set the current directory to test then invoke
javac -classpath xcom:. B.java

Helen Ma
Ranch Hand

Joined: Nov 01, 2011
Posts: 451
Basically, the package xcom specifies where the physical location of the file is. The physical location of A is xcom\A.class

A. Set the current directory to xcom then invoke
javac B.java
Explanation : B uses A, but this command does not specify any classpath to find A.

B. Set the current directory to xcom then invoke
javac -classpath . B.java
Explanation: -cp . means looking at xcom folder, find A. It seems to work. But A's full qualified name is xcom.A
Going to xcom folder find xcom.A However, under xcom, there is not another xcom folder. There is no such a folder xcom\xcom
So, javac cannot find A.
But javac can find B because B is in xcom and javac is used in xcom.
This is the most confusing choice.

C. Set the current directory to test then invoke
javac -classpath . xcom/B.java
Explanation: Go to the current directory test, javac will find xcom folder. Under test directory, javac will find xcom/B.java
It works.

D. Set the current directory to test then invoke
javac -classpath xcom B.java

Explanation: Under test directory, javac will look at xcom. However, there is no other xcom folder under xcom. There is no such a directory xcom/xcom.
Therefore, javac cannot find A. Javac cannot find B neither. Under test directory, there is no such a B.java file. B.java is under xcom.

E. Set the current directory to test then invoke
javac -classpath xcom:. B.java
Explanation: Javac will look at xcom, but cannot find xcom.A . Then, it looks at the current directory, test. It finds xcom.A !
However, javac cannot find B.java because B is under xcom, not under test.

This is the most confusing topic for me, too. This is even more confusing that generics/threads topics, honestly. It is because people nowadays use Eclipse/JBuilder or other tools to compile. We don't use command line to compile ourselves anymore.

Summary:
For javac, -cp looks for all the files that are needed to compile a file. If the files , such as xcom.A is needed, it should look at test directory in order to find xcom. Getting into xcom to find xcom.A means looking for a file xcom\xcom\A.class. There is no such file path.

For javac, to compile the file , such as B.java, javac has to know where B.java is. If it is in the same current directory , fine, just use B.java. If it is in deeper directories, then specify it. Or, if it is in your thumb drive F: , then specify F:\B.java

For java, -cp actually looks for all files , not just A.class, but also B.class . This is because it needs to make sure A.class and B.class still exists. However, in javac, the -cp only looks for the classes (A.class) it needs to compile B.java. This is a big difference between java and javac in the way how they use -cp.
If the current directory is test, the command should be java -cp . xcom.B (it means, java looks at the current directory test, look for xcom.A and xcom.B, and execute xcom.B)
If the current directory is xcom, I don't think the command will work for B. Because B's full name is xcom.B . Under xcom, there is no such a xcom\B.

C Halbe
Greenhorn

Joined: Jul 18, 2008
Posts: 20
Thanks Helen. Your explanation is much clearer than the one given in the book.

So just to summarize,

javac uses the fully qualified name of the .class files to find them, that is, we should specify the classpath such that the last directory in the cp is the super-directory of the leftmost directory in the fully qualified name.

So if the current directory is root directory then the command would be
javac -classpath /foo/test /foo/test/xcom/B.java

right?

Helen Ma
Ranch Hand

Joined: Nov 01, 2011
Posts: 451
Yes. I think the -classpath foo/test should be able to find xcom.A I think javac basically concatenates foo/test with xcom/A.class or foo/test with some other directories if there are any.

Quiz time:
What happens if the package xcom are removed from the A.java and B.java? The fully qualified name of them are now A and B.

1. If the current directory is in xcom,
javac B.java works?
java B? works?
I think so because javac can find A.class in xcom.

2. If the current directory is in test,
javac -cp xcom xcom\B.java works?
java -cp xcom B works?
I think so because javac needs to look at xcom to find A in order to compile B and put B.class in xcom. And java needs to look at xcom to find A and B. Since B is the name of the B.class, so it works.

Correct me if I am wrong. ( This is the most confusing topic for me.)

C Halbe
Greenhorn

Joined: Jul 18, 2008
Posts: 20
What happens if the package xcom are removed from the A.java and B.java? The fully qualified name of them are now A and B.

If the package xcom; is removed from both the classes then, you haven't mentioned what is the new location of those two classes. They must belong to some default directory.
Helen Ma
Ranch Hand

Joined: Nov 01, 2011
Posts: 451
Yes. The author may change the question like this: with the same file structure, remove package xcom, the javac or java commands will be different.

Don't get me started about those stupid light bulbs.

subject: Classpath Related Question