• We’re currently investigating an issue related to the forum theme and styling that is impacting page layout and visual formatting. The problem has been identified, and we are actively working on a resolution. There is no impact to user data or functionality, this is strictly a front-end display issue. We’ll post an update once the fix has been deployed. Thanks for your patience while we get this sorted.

cant write my first java package

rookie1010

Senior member
Hello

I am trying to write my first package program and i have two classes Mammal.java which is like this

// Class Mammal package Mammal;
public class Mammal
{
protected String color;
public void growHair()
{ System.out.println("Hair Growing");
}
}


and dog.java which is like this

//Class Dog public class Dog extends Mammal
{
private int barkFrequency;
public void bark()
{ System.out.println("Dog Barking");
color = "blue";
}
}


both are in the directory E:\Work\programming\java\programs\testing\Mammal

when i do the following from the command prompt i get the responses


E:\>cd work

E:\Work>cd programming\java\programs\testing\mammal

E:\Work\programming\java\programs\testing\Mammal>javac mammal.java

E:\Work\programming\java\programs\testing\Mammal>javac dog.java
dog.java:3: cannot access Mammal
bad class file: .\Mammal.class
class file contains wrong class: Mammal.Mammal
Please remove or make sure it appears in the correct subdirectory of the classpa
th.
public class Dog extends Mammal{
^
1 error

E:\Work\programming\java\programs\testing\Mammal>

what am i doing wrong?
 
There are a couple things to remember here. First, make sure your filenames match your class names so you should have Mammal.java and Dog.java. Second, by convention, use lowercase package names. It's confusing to see Mammal.Mammal because you think one is a nested class of the other. (This would require making your folder name "mammal" as well.) Also, do you even have package statements in your source? I don't see them.

However, the most important thing to know when working with packages is how to deal with the command line. The classpath should no longer point to the directory in which the source or class files are, but rather the directory at the top of the package hierarchy. In your case, you want to be in the testing directory. Then, to compile, you'd type: "javac -classpath . mammal/Mammal.java". Then to compile Dog.java: "javac -classpath . mammal/Dog.java". Note that you can skip compiling Mammal.java because it'll get done automatically when you compile Dog.java. Then, assuming you had a main() in Dog.java, the command to run the program (also from the testing directory) is "java -classpath . mammal.Dog".

So both for compiling and running you specify that the classpath is above the mammal directory ("." means "this directory") and java/javac uses the directory structure to match to package names. When compiling you specify the java file by its path like "mammal/Mammal.java" but when running you specify the qualified name of the class like "mammal.Dog" and it uses the folder structure to find the Dog.class.
 
thanks for the Reply

in Mammal.Mammal is the first Mammal the package name and the second Mammal the class name

i have undesrtoood what you said and have changed the code for the two classes.

//Class Dog
package animal; //changed mammal to animal
public class Dog extends Mammal{
private int barkFrequency;
public void bark(){
System.out.println("Dog Barking");
color = "blue";
}
}

and

// Class Mammal
package animal; //changed Mammal to animal
public class Mammal {
protected String color;
public void growHair(){
System.out.println("Hair Growing");
}
}

i guess you compile the individual components of the package where the directory which contains the directory(package) not form within the package, correct?

so i cant compile from

E:\Work\programming\java\programs\testing\animal (changed Mammal to animal)

but can compile only from

E:\Work\programming\java\programs\testing

correct?

Can a class and its containing package not share the same name
e.g. if i have a class named Mammal, can its package not be Mammals?

one last question, if i declare an attribute/variable protected say in Mammal.java, i guess all the classes in the package animal can access the variable but classes outside the package cannot access it, correct?

one more question 🙂

should not
javac -classpath . mammal/Dog.java

be
javac -classpath . /mammal/Dog.java

 
Looks like you pretty much understand. The code looks good.
Can a class and its containing package not share the same name
e.g. if i have a class named Mammal, can its package not be Mammals?
I assume you mean the package "Mammal" (no 's' on the end). I believe you can a class named the same as a package, although I'm not entirely sure. I know the c# compiler doesn't allow you to use the same name for a namespace and class (equivalent to package and class in java) but namespaces in c# are kinda dumb compared to java. The definitive answer is that nobody ever uses uppercase names for packages, simply by convention so it's a non-issue. (I shouldn't say never, but I've never seen non-beginners do it).
one last question, if i declare an attribute/variable protected say in Mammal.java, i guess all the classes in the package animal can access the variable but classes outside the package cannot access it, correct?
That is correct. It's something that I don't really like because I think that sun thought that people would do much more package-centric design than is actually normal. Most of the time, people just pretend that protected means access to class and subclasses only. If I use it in a package-protected sort of way, I usually comment it specifically so people don't think I'm just doing an ugly hack.
javac -classpath . /mammal/Dog.java
No. I'm not sure what effect this would have on windows, but on any *nix it would look for a folder called mammal in the root directory. In your example in windows it might look for E:\mammal\Dog.java. What you could do is "javac -classpath . ./mammal/Dog.java", which looks for mammal in the current directory and is essentially equivalent to my original example. Do note the space between "-classpath ." and "mammal/Dog.java" in the original example. It's kind of important.

Edit: I should also comment on the use of "/" in the paths. On windows you can use "\" like normal paths and it'd be somewhat less confusing. But you can use the "/" to mean the same thing and it's more portable because almost every other operating system on the planet does it that way.
 
thanks for the reply and clearing my misconceptions about packages

most of the time, people just pretend that protected means access to class and subclasses only.

you mean to say that the addition is all other classes which may or may not be subclasses have access to the protected variables as long as they are part of the same package?

what is a *nix?

you mean to say that

javac -classpath . /mammal/Dog.java
would cause windows to look for E:\mammal\Dog.java


hey ned, i thought i might do a bit of commandf line development before i switch to an IDE, why do you recommend bluej instead of netbeans?
 

hey, i just tried to access a protected variable fro mthe application class (Packaging.java) where the application class, superclass and subclass are part of a package (Animal). but i can access the protected variable(defined in the superclass) only form the subclass not fromt the application class.


is that teh case, that one cannot access a protected variable from the appliction class even though it is apart of the same package?

my code for the three classes is

import animal.*;
//Class Dog
public class Dog extends Mammal{
private int barkFrequency;
public void bark(){
System.out.println("Dog Barking");
color = "blue";
}
}

// Class Mammal
package animal;
public class Mammal {
protected String color;
public void growHair(){
System.out.println("Hair Growing");
}
}

import animal.*;
public class Packaging {
public static void main (String args[]){
Mammal mammal = new Mammal();
mammal.growHair();
mammal.color="blue";
}
}

i am getting the following error

E:\Work\programming\java\programs\testing>javac -classpath . ./animal/Dog.java

E:\Work\programming\java\programs\testing>javac -classpath . ./animal/Packaging.
java
./animal/Packaging.java:6: color has protected access in animal.Mammal
mammal.color="blue";
^
1 error

E:\Work\programming\java\programs\testing>
 
Originally posted by: Ned Flanders
Since your obviously new at java, why not try a beginners development enviroment? BlueJ (www.blueJ.org) rocks.
I'd disagree with that. Getting a handle on the underpinnings is key before taking the blue pill that is the world of ides. (That was punny 😛).

I think he's doing pretty well at figuring stuff out.
 
Originally posted by: rookie1010
you mean to say that the addition is all other classes which may or may not be subclasses have access to the protected variables as long as they are part of the same package?
Yep.
what is a *nix?
Any unix or unix-like operating system. Linux for instance, or any of the BSDs. Or solaris, where java was invented.
javac -classpath . /mammal/Dog.java
would cause windows to look for E:\mammal\Dog.java
That would seem logical. I don't have a windows machine to test on, maybe you can tell me 😉
 
Originally posted by: rookie1010
... code ...
i am getting the following error

E:\Work\programming\java\programs\testing>javac -classpath . ./animal/Dog.java

E:\Work\programming\java\programs\testing>javac -classpath . ./animal/Packaging.
java
./animal/Packaging.java:6: color has protected access in animal.Mammal
mammal.color="blue";
^
1 error

E:\Work\programming\java\programs\testing>
I don't see a package statement in either Dog.java or Program.java. You wouldn't have to import animal.* if they were in the animal package.
 
thanks for the reply and for the vote of confidence

i placed Packaging.java and Dog.java outside the animal package (that is in the tetsing directory) and then did javac Packaging.java, i got


E:\Work\programming\java\programs\testing\animal>cd ..

E:\Work\programming\java\programs\testing>javac Packaging.java
Packaging.java:6: color has protected access in animal.Mammal
mammal.color="blue";
^
1 error

E:\Work\programming\java\programs\testing>


whereas if i do javac Dog.java i get




E:\Work\programming\java\programs\testing>javac Dog.java

E:\Work\programming\java\programs\testing>


why is this, i seem to be able to import animal if the class is a superclass, but if it is an application class then i cant import the library, it says that the attribute is protected.


perhaps i have not been able to form a proper package, and it is some sort of defualt behaviour that the subclass knows that it has a superclass (dont know if i am making any sense here)


 
Protected access means that any class in the same package or any subclass can access the variable. Dog can access Mammal.color no matter what package it is in because it subclasses Mammal. Packaging cannot access Mammal.color because it is neither a subclass nor in the animal package. If you move Packaging.java back into the animal folder and put "package animal;" at the top, you will be able to access mammal.color.

As a side note, there is another scope called "package-protected" (I mentioned this above but didn't use the term quite properly) also known as "default scope." It means that only classes in the same package may access the variable or method and not subclasses from different packages (like Dog in your last example). You specify it by not putting any access modifier on the member. If you just delete the "protected" word from Mammal.color, Dog will fail to compile unless you move it back into the animal package.
 
hey dude

thanks for all the help

the import animal.* threw me off, i thought it would enable classes to access protected variables.

my understanding now is that the Packaging class will not be able to access the Mammal.color member unless it is a member of the Animal package
what i found even more intesresting, is that i commented out package animal in Mammal.java and Packaging.java had the compile problem again even though Mammal.class has not changed, at compile time does Packaging.java access Mammal.java or Mammal.class?

i tried out "package protected" by taking out the modifer protected from "String color" and i cant access color from even the dog class

also Dog.java requires import animal.* if it is not placed within the animal directory though it is a subclass.

till now i have figured out that the iport animal.* declaration does not have an effect on Mammal.java but with Dofg it enables the Dog class to access the protected members in classes of its own package
 
In your case, when you took "package animal;" out of Mammal.java, the compiler would ignore Mammal.java because it's no longer on your classpath. Mammal.class is still on the classpath because it is in the animal package and in the animal folder.

The import animal.* doesn't really make a difference in what you're allowed to accesss. It just tells the compiler that if there is a class referenced without a fully qualified name, then it should look in the animal package to find which class you mean. You could get the same effect by removing the import line and referring to Mammal as animal.Mammal.
 
thanks for the reply

what do you mean by it is on the classpath

Mammal.class can be on the classpath while Mammal.java is not on the classpath.

ah so if i have import animal.* and import cars.*, the compiler would look in animal and cars packages for any class it cant find.

i feel silly asking you basic questions, is there any online resource you recommend that i read before i ask basic questions about classpath and other basic issues
 
Sun's java tutorial is what I usually recommend: http://java.sun.com/docs/books/tutorial/
It doesn't appear to have a section specifically on classpaths, but it might help.

So, to define classpath properly: it's a list of directories in which the compiler and runtime will look for class definitions. The compiler can also use java files, obviously. In order for a given class to be on the classpath it must in a folder structure that matches the package structure with the top level directory being in the classpath (hence why you go up above the animal directory). If a class is in the default package (no package statement in the code), it must be located directly in a folder on the classpath.

In your case, Mammal.class was on the classpath because it was in the animal package and in the animal folder. Mammal.java was not on the classpath because it was in the default package and it is not in the folder that is on the classpath ('testing' in this case).

Now I will point out that this is all conjecture. I just tested it out on my mac and when do the equivalent of removing the "package animal;" from Mammal.java I get an error saying that the java file doesn't contain the correct class, which would mean that my above statements are wrong. Apparently it does find the .java file but complains about it. I then put the animal folder on the classpath: "javac -classpath animal Packaging.java" and it compiles fine (which makes sense).

I hope I'm not confusing you now 😛
 
Back
Top