• Google+
  • Twitter
  • YouTube
  • RSS
  • Facebook

Java Package: How To Structure Your Java Code Project With Packages

Packages in Java are used organize your code files and prevent namespace conflicts (where two classes have the same name).

Let’s take a look at a simple example. The following example assumes you’re on a Windows platform, but Java works much the same on UNIX.

Java Packages: A Simple Working Example

Let’s say we are in a directory called c:work.

We are going to place some code in a package called aquarium. The aquarium package will itself be a sub-package of a caveofprogramming package.

We place the code in a subdirectory of aquarium which is itself in a directory called caveofprogramming.

So the directory structure looks like this:

Working directory: c:work
Java code: c:workcaveofprogrammingaquariumFish.java

Code (Fish.java):

package caveofprogramming.aquarium;

public class Fish {
	public static void main(String [] args) {
		System.out.println("hello");
	}
}

Note that at the top of this file we have a package declaration that says the Fish class is in a package called aquarium which is a sub-package of caveofprogramming.

Now, in c:work we can type the following to compile Fish.java:

javac caveofprogrammingaquariumFish.java

Now, how do we run this program? Where do we run it from?

The magical answer to this question is: we can run it from anywhere. The only catch is that we must tell java to expect to find classes in c:work. Also we must tell java to run caveofprogramming.aquarium.Fish, to give the compiled class its fully-qualified name.

There are two ways to set the “class path”, which tells java what directories to look in for classes.

  1. Set the CLASSPATH environment variable. This is a semi-colon separated list of paths where java should look for classes.
  2. Specify the classpath on the command line to java (or set it in your IDE if you’re using one).

We’ll take the second approach here. From anywhere we like, we type the command:

C:>java -cp c:work caveofprogramming.aquarium.Fish
hello

And as you can see, the program runs. Magic!

Note that when we supply a file name to javac, we specify the actual file — complete with an ordinary slash-separated directory path and .java file extension.

However, once the class is compiled, we no longer use directories or file extensions to refer to the compiled class file. Instead, we use just dots to form the package ‘path’ and just the name of the class, not the file that contains it:
(caveofprogramming.aquarium.Fish)

In a nutshell, javac deals with files, whereas java deals with classes.

Multiple Classpaths

What if you’ve got classes on several classpaths?

First, let’s look at compiling an application, where some files are on one classpath, and other files on another.

I’ve modified Fish.java to use a Java class in another package. This package is also a sub-package of caveofprogramming, called stuff instead of aquarium (you should choose more imaginative names for your own packages!).

We import all classes in the stuff package like this:

import caveofprogramming.stuff.*;

… but we could also import a particular class like this:

import caveofprogramming.stuff.Bubble;

Here’s the complete code.

Fish.java:

package caveofprogramming.aquarium;

import caveofprogramming.stuff.*;

public class Fish {
	public static void main(String [] args) {
		Bubble bubble = new Bubble();
		bubble.blow();
	}
}

Bubble.java looks like this:

package caveofprogramming.stuff;

public class Bubble {
	public void blow() {
		System.out.println("Blowing bubbles!");
	}
}

Let’s say that for reasons that are barely imaginable, we’ve put Bubble.java under a folder called c:workclasses.

Of course, since it’s in the caveofprogramming.stuff package, it actually needs to be placed in a caveofprogrammingstuff subdirectory of c:workclasses.

So now we have two files, as follows:

Working directory: c:work
Fish.java: c:workcaveofprogrammingaquariumFish.java
Bubble.java: c:workclassescaveofprogrammingstuffBubble.java

All we need to do is supply the extra classpath to javac; we need to tell it that there are files under both c:work and c:workclasses.

There’s no need to specify Bubble.java itself; the classpath together with the package name are all that javac needs to find it.

So from c:work we can issue the following command; note the semicolon-separated list of classpaths:

javac -cp c:work;c:workclasses caveofprogrammingaquariumFish.java

The java command is exactly the same as before, except we also need to specify the extra classpath (otherwise how would it know where to find Bubble.class?).

java -cp c:work;c:workclasses caveofprogramming.aquarium.Fish

Using Code in Jar Files

What if you’ve packaged some classes in a jar file?

Let’s go to c:workclasses and type this (after compiling as above to create the Bubble.class file):

jar cvf test.jar caveofprogramming

We’ll then move test.jar to c:work.

Now we can compile Fish.java like this:

javac -cp c:work;c:worktest.jar caveofprogrammingaquariumFish.java

… simply naming test.jar in the classpath.

Likewise, when we want to run Fish.class, we can once again just add the jar file to the classpath and run the code from anywhere:

C:work>java -cp c:work;test.jar caveofprogramming.aquarium.Fish
Blowing bubbles!

Putting Your Program in a Jar File

Of course, we can also put the main class in a jar file itself (after compiling, of course!):

c:work> jar cvf fish.jar caveofprogramming
added manifest
adding: caveofprogramming/(in = 0) (out= 0)(stored 0%)
adding: caveofprogramming/aquarium/(in = 0) (out= 0)(stored 0%)
adding: caveofprogramming/aquarium/Fish.class(in = 358) (out= 265)(deflated 25%)
adding: caveofprogramming/aquarium/Fish.java(in = 201) (out= 144)(deflated 28%)

So now we’ve put the main program in fish.jar, and test.jar contains other files that main.jar depends on. We can run the program like this:

java -cp c:worktest.jar;c:workfish.jar caveofprogramming.aquarium.Fish
Blowing bubbles!

Easy!

Unfortunately things can get more hairy than this when you start doing stuff like adding a main class to your jar manifest, using ANT, using the -jar option, etc. If you’re not careful, you can end up feeling like you don’t know which classpath is being taken note of and which one isn’t, or where you should specify classpaths in the first place.

Google is always very helpful. If you keep in mind the principles here, you’ll have a good platform to start from.