• Post Reply Bookmark Topic Watch Topic
  • New Topic

Compiling, the classpath, and packages  RSS feed

 
nick woodward
Ranch Hand
Posts: 382
12
  • Mark post as helpful
  • send pies
  • 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


 
Campbell Ritchie
Marshal
Posts: 56600
172
  • Likes 1
  • Mark post as helpful
  • send pies
  • 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: 382
12
  • Mark post as helpful
  • send pies
  • 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: 56600
172
  • Mark post as helpful
  • send pies
  • 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: 382
12
  • Mark post as helpful
  • send pies
  • 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: 56600
172
  • Mark post as helpful
  • send pies
  • 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: 56600
172
  • Likes 1
  • Mark post as helpful
  • send pies
  • 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.
 
Henry Wong
author
Sheriff
Posts: 23295
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Likes 1
  • Mark post as helpful
  • send pies
  • 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: 382
12
  • Mark post as helpful
  • send pies
  • 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
 
Mike. J. Thompson
Bartender
Posts: 689
17
  • Mark post as helpful
  • send pies
  • 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
  • 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 ;)
 
Tim Holloway
Saloon Keeper
Posts: 18800
74
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • 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: 382
12
  • Mark post as helpful
  • send pies
  • 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: 56600
172
  • Mark post as helpful
  • send pies
  • 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: 18800
74
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • 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: 56600
172
  • Mark post as helpful
  • send pies
  • 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.
 
Don't get me started about those stupid light bulbs.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!