Win a copy of Classic Computer Science Problems in Swift this week in the iOS forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

A class is not seeing another public class that lives within the package  RSS feed

 
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello,

I'm following the example on page 174 of the OCA sybex study guide which uses classes in two packages: pond.duck and pond.swan to show private and default access.

I've created two java files one for FatherDuck and one for BadDuckling as is laid out in the book but when compiling the two, BadDuckling fails with a 'cannot find symbol' error on FatherDuck.
Could someone explain to me why this is or whether I need to structure the two classes in some specific way?

Thanks!
 
Marshal
Posts: 58829
179
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the Ranch

Please supply more details of what you have written, because many of us don't have the book.
 
A Lauran
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:Welcome to the Ranch

Please supply more details of what you have written, because many of us don't have the book.



Sorry, new to this so here we go:

So we have two classes:


and



Both FatherDuck and BadDuckling are in the pond.duck package so I have a 'duck' folder within a 'pond' folder and have both classes saved there.

With my directory in the command line set to C:\temp\pond\duck, FatherDuck.java can be compiled successfully. But trying to compile BadDuckling.java I get the following error:

 
A Lauran
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:Welcome to the Ranch



And thank you!
 
author
Sheriff
Posts: 23484
138
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

A Laran wrote:
With my directory in the command line set to C:\temp\pond\duck, FatherDuck.java can be compiled successfully. But trying to compile BadDuckling.java I get the following error:



Try setting your current working directory to C:\temp, and compiling pond\duck\FatherDuck.java and pond\duck\BadDuckling.java files respectively. I am assuming that you don't have a CLASSPATH set, and in this case, the classpath is assumed to be the current working directory.

Henry
 
A Lauran
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Henry Wong wrote:

A Laran wrote:
With my directory in the command line set to C:\temp\pond\duck, FatherDuck.java can be compiled successfully. But trying to compile BadDuckling.java I get the following error:



Try setting your current working directory to C:\temp, and compiling pond\duck\FatherDuck.java and pond\duck\BadDuckling.java files respectively. I am assuming that you don't have a CLASSPATH set, and in this case, the classpath is assumed to be the current working directory.

Henry



Hi Henry,

If it is assumed to be the current working directory, both classes live within pond\duck so why would it be able to see FatherDuck when compiling that but not when compiling another class?
 
Marshal
Posts: 5626
387
BSD
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

A Lauran wrote:duck.quack();                   // DOES NOT COMPILE
System.out.println(duck.noise); // DOES NOT COMPILE


That's correct.

Because you are calling method which is private to FatherDuck class, same as noise variable is private to FatherDuck class, that means only FartherDuck class can use them while you trying to do so from BadDuckling class.
 
Henry Wong
author
Sheriff
Posts: 23484
138
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

A Lauran wrote:
If it is assumed to be the current working directory, both classes live within pond\duck so why would it be able to see FatherDuck when compiling that but not when compiling another class?



The class that is being compiled is located from source, which is specified in the command line. The classes which are needed by the class that is being compiled is located from the classpath. Without the classpath being set, it is the current working directory. Since you are in the C:\temp\pond\duck directory, and the BadDuckling class needs the pond.duck.FatherDuck class, it will try to locate it in the C:\temp\pond\duck\pond\duck\FatherDuck.class file.

So, you either have to place the current working directory in the correct directory, or set the classpath to be the same.

Henry
 
Henry Wong
author
Sheriff
Posts: 23484
138
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Liutauras Vilda wrote:
Because you are calling method which is private to FatherDuck class, same as noise variable is private to FatherDuck class, that means only FartherDuck class can use them while you trying to do so from BadDuckling class.



This is the next issue. Once you get the compiler to find the class, it will be complaining about the fields which are not accessible.

Henry
 
A Lauran
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Henry Wong wrote:

A Lauran wrote:
If it is assumed to be the current working directory, both classes live within pond\duck so why would it be able to see FatherDuck when compiling that but not when compiling another class?



The class that is being compiled is located from source, which is specified in the command line. The classes which are needed by the class that is being compiled is located from the classpath. Without the classpath being set, it is the current working directory. Since you are in the C:\temp\pond\duck directory, and the BadDuckling class needs the pond.duck.FatherDuck class, it will try to locate it in the C:\temp\pond\duck\pond\duck\FatherDuck.class file.

So, you either have to place the current working directory in the correct directory, or set the classpath to be the same.

Henry



Thank you, this makes sense! I definitely did not catch on to the fact that the required classes were being grabbed from C:\temp\pond\duck\pond\duck\FatherDuck.class

So am I correct in understanding that I'd have to set the classpath to C:\temp so that it looks in C:\temp\pond\duck.FatherDuck.class? And I wouldn't want to set it to C:\temp\pond\duck?
 
Liutauras Vilda
Marshal
Posts: 5626
387
BSD
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
How about, just give a try?
 
A Lauran
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Liutauras Vilda wrote:How about, just give a try?



So I set my classpath variable to point to C:\temp and am getting the same failure so my question was just to clarify whether that should definitely work ? (in which case, my set up must be wrong).

I tried calling javac and java in the command line and both were recognised which would suggest the PATH and CLASSPATH variables are set up correctly
 
Liutauras Vilda
Marshal
Posts: 5626
387
BSD
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't know your setup, but I can try to explain in my words, so you could try to re-assemble problem solution on your side.

Let's go from the beginning.

There is a file system's directory structure and Java's package structure. That's one. Note, structure I've made it slightly more complicated than it actually could be.

Second is, that to an end-user they both look the same (and in fact they are), if you open some file explorer and look to two let's say directories "aa" and "bb", you couldn't say if one of these directories play any role in an existing (any) Java source file.

Let's say currently you are in the directory "Documents" (navigated through either command-prompt in case of Windows, or terminal in case of UNIX flavour system) and you have such setup:

Class A looks like:

Class B looks like:

So, what is important to know. You have at the moment only source files, you don't have them compiled yet. As you see, class A doesn't appear to be in any user's defined package (so it is in default/no-named package). Contrary wise, class B is in a package io.github.liutaurasvilda

Remember from earlier, that Java package and file system's directory looks same if we were to talk about the directories (or for other people maybe easier to understand - folders).
And if you look once again now how the source files are located in the file system currently, you'd notice, that there is missing mentioned part "io.github.liutaurasvilda", this is what class B has as its package.

So, after you compile your B class's source file "B.java", your compiled file "B.class" must reside in:

or if you look at it as tree structure in your head (ellipsis mean "could be anything"):

Now. The classpath is, where to look for *.class files EXCEPT its package structure. That means that Java knows how to find class files once you show to it, where classes package is located.

So let's assume I compiled my both classes, class A has no package statement, class B has as specified above, so I currently am in the Documents directory, so what I supposed to end up with is:

When you compile classes which contain package statements, you can tell compiler to create packaging structure if it doesn't exist on file system already, and that could be done as next..

In case you are in Documents direcotry:
javac -d temp temp/B.java

In case you are in Documents/temp directory:
javac -d . B.java

(note: . means present working directory)

Once you do that, in your directory Documents/temp the directories /io/github/liutaurasvilda appear along with B.class file inside.

So, you got compiled all stuff and once again, you have:

Now you want to run Java program which's starting point is class A. How you do that. Currently you are in directory Documents.


;  <-- classpath separator in Windows
:  <-- classpath separator in UNIX flavour OS

The . means, that look for classes in present working directory (meaning in /Documents), and temp means, that look for classes in /Documents/temp, documents get assumed because you are in Documents when issuing such compile instruction.

In case class A also had package statement let's say liu.test, then in an execution instruction you'd need specify class name along with package name, such as:


----
If you can't re-assemble solution, please show exact structure where your files reside and please show us what instruction you issue from your command-prompt.
 
A Lauran
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you - but i'm still struggling to understand so I will copy my set up:

So I my folder structure like so:
C:\temp\pond\duck
and within here, I have a FatherDuck.java and BadDuckling.java



and



My classpath is sset to:
C:\temp
and my directory in the command line is
C:\temp\pond\duck

From the command line, I call javac FatherDuck.java which compiles to add FatherDuck.class to C:\temp\pond\duck

Now when I call javac BadDuckling.java, I get the above error.
 
Liutauras Vilda
Marshal
Posts: 5626
387
BSD
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Read carefully Henry’s post which is one before the last one he posted, he explained there couple of scenarios. Try one or another, you should be able to nail it on your own.

One thing, when you say your classpath is set to c:\temp, can you please show some evidence how you achieve that?
 
A Lauran
Greenhorn
Posts: 11
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Right just retried setting the Classpath to C:\temp from scratch and it works!  thanks so much everyone
 
Consider Paul's rocket mass heater.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!