Granny's Programming Pearls
"inside of every large program is a small program struggling to get out"
JavaRanch.com/granny.jsp
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Jeanne Boyarsky
  • Liutauras Vilda
  • Campbell Ritchie
  • Tim Cooke
  • Bear Bibeault
Sheriffs:
  • Paul Clapham
  • Junilu Lacar
  • Knute Snortum
Saloon Keepers:
  • Ron McLeod
  • Ganesh Patekar
  • Tim Moores
  • Pete Letkeman
  • Stephan van Hulst
Bartenders:
  • Carey Brown
  • Tim Holloway
  • Joe Ess

Classpath Related Question  RSS feed

 
Greenhorn
Posts: 20
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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

Can someone please explain me why answer C is correct and why other answers are wrong?
 
Ranch Hand
Posts: 451
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.

Correct me if I am wrong. I am still a learner about this confusing topic.


 
C Halbe
Greenhorn
Posts: 20
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 451
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 20
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

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
Posts: 451
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
Consider Paul's rocket mass heater.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!