• 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 Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Ron McLeod
  • Rob Spoor
  • Tim Cooke
  • Junilu Lacar
Sheriffs:
  • Henry Wong
  • Liutauras Vilda
  • Jeanne Boyarsky
Saloon Keepers:
  • Jesse Silverman
  • Tim Holloway
  • Stephan van Hulst
  • Tim Moores
  • Carey Brown
Bartenders:
  • Al Hobbs
  • Mikalai Zaikin
  • Piet Souris

Compiling, the classpath, and packages

 
Ranch Hand
Posts: 386
12
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello! I've been struggling with this over the last day or so. Wondered if anyone could help. The java tutorials don't seem, in my opinion, to be very clear on this, and another guide I've read made things slightly clearer, but I'm still struggling to apply it.

Here's my file structure:



in C2 there is a reference to C1.

I compile C1 from the root directory with:


and C2 with:


all is good, but then I add the relevant packages to mirror their directory structure (I'm doing this to understand rather than because I think it's the way it should be done) and try to compile again.

With C2 I try

with no luck

Is the compiler trying to find C1 (referenced in C2) from the relative position of C2? IE it's trying to look here:

correct? (this is what i read elsewhere - but i'm not entirely sure how the compiler ought to know the package C1 is contained within anyway)

Using -cp "." from the root folder seems to make sense because of C1's package, but it doesn't work, and again, I'm left wondering why it should. I feel like I've got myself completely and utterly confused now!

Any help, or direction, even a minor hint, would be much appreciated!

Nick


 
Marshal
Posts: 74004
332
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You don't supply a classpath to compile; you supply the name of a .java file. So your second example which didn't have C2.java at the end won't work.
 
nick woodward
Ranch Hand
Posts: 386
12
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:You don't supply a classpath to compile; you supply the name of a .java file. So your second example which didn't have C2.java at the end won't work.



wow, I'll have to take a look when I'm back from work (all this classpath stuff has made me late ), thanks for the quick response!
 
Campbell Ritchie
Marshal
Posts: 74004
332
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You're welcome

I presume your .java files start with the package declaration
package com.woodward.oca.classpath;
You usually have a src (or similar) folder with a structure inside corresponding to the package structure and a classes (or bin or similar) folder with a similar included structure. You would go into the classes folder and use the -d option which puts the output files into the requisite directories
classes:> javac -d ..\src\com\woodward\oca\classpath -cp "com\woodward\oca\classpath" C2.java
At least I think that is what you do; I am sure somebody will correct me if I am mistaken.

I think you don't have to write com\woodward\oca\classpath\C2.java but I am not certain.

Classpath is an unusual name for a package. Don't let woodward.com find out you are using that package name, unless you happen to own that web address (‍).
 
nick woodward
Ranch Hand
Posts: 386
12
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
tell noone!

its ok, i doubt they'll be using it as a way to claim the gigabytes of original and valueable IP i've definitely got here.... give it another month or so, or let me sign up to the drive first....

anyway, unfortunately i think that was just a typo in the first post. i have re-run:



and its not finding C1. I should've mentioned that that is the error i'm getting. 'cannot find C1'.

C1 is in package com.woodward.oca.classpath, C2 is in com.woodward.oca.classpath.classes

is there no way to get more detail from the error? like where it's looking?

hang on - when i use cp, does that override the environment variable classpath? i've been specifying the classpath from the root folder, but does the compiler understand that i want it to start its search from the current / active directory? i'm going to try:



fingers crossed......

*edit: nope. swear that was going to be it....

** edit - yes it was! i just also forgot the import statement

so i have to have two paths in the cp - one to tell it to start from the current directory, and the other to match the package name (or route to the class(es)).


 
Campbell Ritchie
Marshal
Posts: 74004
332
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think you are looking for the com.woodward.oca.classpath.C!.java file in the ...\com\woodward\oca\classpath folder. That means you would have to find a \com folder in the classpath folder. You need to tell the -cp option to start looking from where it will find the appropriate \com folder. Try
... -cp . ...
because you are probably going to find that \com folder in the current directory.

And it looks as though I was mistaken. That is nothing unusual. And nobody found me out. That is unusual.
 
Campbell Ritchie
Marshal
Posts: 74004
332
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Look in the documentation for the javac tool. Try here and I think you will find that the -cp option does in fact completely override the system classpath. Another reason for not setting a system classpath.
 
author
Posts: 23907
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

nick woodward wrote:


and its not finding C1. I should've mentioned that that is the error i'm getting. 'cannot find C1'.

C1 is in package com.woodward.oca.classpath, C2 is in com.woodward.oca.classpath.classes

is there no way to get more detail from the error? like where it's looking?



The classpath is the root location to search for the required classes. So, if the classpath is "\com\woodward\oca\classpath", and while compiling the C2 class, it needs to find the C1 class, which is in the "com.woodward.oca.classpath" package... then, the java compiler will look for the C1.class file in the "\com\woodward\oca\classpath\com\woodward\oca\classpath" directory.

Henry
 
nick woodward
Ranch Hand
Posts: 386
12
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Henry Wong wrote:

nick woodward wrote:


and its not finding C1. I should've mentioned that that is the error i'm getting. 'cannot find C1'.

C1 is in package com.woodward.oca.classpath, C2 is in com.woodward.oca.classpath.classes

is there no way to get more detail from the error? like where it's looking?



The classpath is the root location to search for the required classes. So, if the classpath is "\com\woodward\oca\classpath", and while compiling the C2 class, it needs to find the C1 class, which is in the "com.woodward.oca.classpath" package... then, the java compiler will look for the C1.class file in the "\com\woodward\oca\classpath\com\woodward\oca\classpath" directory.

Henry



yeah, this is what i originally thought but somewhere along the way (i guess when it didn't work the first time) i got massively confused - i just went back and removed everything except for "." and now its working. i'm ashamed to say it must have been the missing import statement....

think i'm going to spend a bit of time without textpad, and putting files in separate locations.

one question though - how does the compiler know what 'package' C1 is in? given that the 'directions' (so to speak) are in C1 itself, supposedly the file that it can't find?

thanks for that link Campbell
 
Bartender
Posts: 689
17
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

nick woodward wrote:
one question though - how does the compiler know what 'package' C1 is in? given that the 'directions' (so to speak) are in C1 itself, supposedly the file that it can't find?



Either the import statement tells the compiler where to find the class, or you need to use the fully qualified class name in your code. Imagine the following two classes:





So the import statement in the file that SecondClass is defined in says it wants to import a.b.c.FirstClass. The compiler will look at your class path and search all the locations it finds on there until it finds a.b.c.FirstClass.

Now you could re-write SecondClass as follows:



Notice how the fully qualified classname includes the package name followed by the class name.

Also remember that the classpath can have more than one location on it, and the locations do not have to be directories. They can also be JAR files, or a mixture of both. This is how you use third party libraries in your application. You place the jar file(s) in a known location and when you start your application you set the classpath to include the jar files.
 
Mike. J. Thompson
Bartender
Posts: 689
17
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:And it looks as though I was mistaken. That is nothing unusual. And nobody found me out. That is unusual.



For what it's worth I did notice, but didn't get chance to reply until now and you'd realised yourself. Of course, I don't expect you to believe me ;)
 
Saloon Keeper
Posts: 24295
167
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Quick synopsis:

Classpath plays 2 roles.

At compile time (javac), it's the location(s) of class definitions needed to compile the supplied java source files. Rather like the "include" path in C/C++.

At run time, it's the location(s) of class definitions needed to execute the java class code. Rather like C/C++ libraries.

These 2 classpaths may or may not be identical, although they must be compatible, since if you compiled with XYZClass version 5,4 and you executed with XYZClass 3.1, there might be essential differences in the properties and methods of the 2 versions.

A classpath is a concatenation of directories and/or jar files. Classpaths are not recursive. Meaning that you cannot put a jar inside another jar and see any of the classes within the internal jar. Nor can you put a jar within a directory and have the classes in that jar be seen. A notable (possibily confusing) exception to that rule is that in a Java webapp, the WEB-INF/lib directory does contain jars, but making the classes within those jars visible is accomplished by the webapp server's specialized class managers, not the default action of the JVM. In addition to explicit classpaths (if any), the JVM contains several libraries that are automatically included, such as the one that defines java.lang.Object.

When you refer to an unqualified class name, first the local classfile is checked, then the local package is checked, then any import statements ending with "*" are checked, then the default package is checked. If I've got the order wrong, someone please correct me. I find it safest not to assume, so I either explicitly specify package names or make sure that the class in question has an unambiguous name so that in either case, I don't have to worry about search order.

 
nick woodward
Ranch Hand
Posts: 386
12
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mike. J. Thompson wrote:

nick woodward wrote:
one question though - how does the compiler know what 'package' C1 is in? given that the 'directions' (so to speak) are in C1 itself, supposedly the file that it can't find?


Either the import statement tells the compiler where to find the class, or you need to use the fully qualified class name in your code. Imagine the following two classes:



of course it does! i think this just frustrated me over the last day or so, and i stopped thinking clearly.

thanks again
 
Campbell Ritchie
Marshal
Posts: 74004
332
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mike. J. Thompson wrote: . . .
. . .

Don't you have to qualify both occurrences of the class name?
 
Tim Holloway
Saloon Keeper
Posts: 24295
167
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:

Mike. J. Thompson wrote: . . .
. . .

Don't you have to qualify both occurrences of the class name?



It's definitely safer that way. Although unless there's a local "FirstClass" that's a subclass of a.b.c.Firstclass (warning: do not try this at home!), then you'd expect to see a compiler error on incompatible class assignment.
 
Campbell Ritchie
Marshal
Posts: 74004
332
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Tim Holloway wrote:. . . (warning: do not try this at home!) . . .

No, try it on somebody else's computer and wreck that

More seriously, I think you should get into the habit of, “please try this at home.” If your program isn't accessible to naughty people via the net, and you don't try to delete important files (or something similarly daft), you should try it out and see what happens. If it goes horribly wrong and crashes, you have learnt what doesn't work. Eventually the light bulb will go on and you will have learnt something which does work.
 
Saloon Keeper
Posts: 1277
38
Eclipse IDE Postgres Database C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Tim Holloway wrote:Quick synopsis:
...

When you refer to an unqualified class name, first the local classfile is checked, then the local package is checked, then any import statements ending with "*" are checked, then the default package is checked. If I've got the order wrong, someone please correct me. I find it safest not to assume, so I either explicitly specify package names or make sure that the class in question has an unambiguous name so that in either case, I don't have to worry about search order.



Your whole answer was awesome, gave it a thumbs-up after six years, but I want to focus on the:

" first the local classfile is checked, then the local package is checked, then any import statements ending with "*" are checked, then the default package is checked."
You asked if you got the order wrong, someone please correct you...nobody did, which is something.

I was just watching someone who knows Java inside out, but often uses non-standard terminology, and also will show wrong ways of doing things or worst practices because they feel that is how you get to know all the Real Dirt the best.

As in so many cases in Java and other languages, there is a simple clear solution to how to write things so that you don't need to remember Arcane Rules and Corner Cases and that is the best way to write code.

However, the "What actually happens when someone does this goofy thing?" questions are important for the Certification Exams, and to defend them, also important when doing Code Reviews (maybe as a second or third approver rather than the owner of that code) on large teams with personnel of varying experience levels.  Those are real situations, and in Real Life one has to decide whether to reject a change that doesn't adhere to one's personal Best Practices.  If it is going to lead to wrong behavior or leave a land mine for the next developer, yes, if it just isn't the way you like to read it, perhaps better not so as to avoid getting a reputation for trying to force one's personal coding standards on other team members, etc.

For normal, non-static imports, this dude answers "Who wins when there is a conflict for a class name in the face of imports?"

They say:
1. Explicitly Imported Classes.  You ASKED for this EXPLICITLY, you are going to get it...
2. "Current Working Directory" -- I don't like this verbiage.  I believe they mean the same package as that which the calling code is in.  The description of "Current Working Directory" is something I have also seen elsewhere in this context in tutorial material, and found quite confusing.  There is a clear notion of it when doing C/C++, i.e. where would a file go if we just did an fopen("unqualified_file.txt") and I don't like using the terminology for other concepts.  For one thing, if all your sources are in /src and you compile them using "-d" then the code in the same source directory is running "in different working directories at runtime" depending on the package that each is placed in at the top of their sources.  This terminology is bad and confusing, but I've unfortunately seen it used in various places.
3. What he calls implicit imports, others call wildcard imports, and the JLS calls On-Demand Imports.  e.g. java.util.*;

If there is any real chance of an ambiguity, I'd rather see qualified.fully.ClassName myself, but for the OCJP you are supposed to know these edge behaviors.

What is the correct terminology for the correct sequence here?
 
Consider Paul's rocket mass heater.
reply
    Bookmark Topic Watch Topic
  • New Topic