Other Topics

Packages

Packages are a way to group classes. They resolve several problems that arise in larger projects. When developing re-usable classes, you need to worry about name conflicts. You might use class names in your project that are the same as those used by someone else. To prevent this, you can use the package name as part of your class names. Then, when integrated into another project, your names will be unique.

Packages are used in software distribution to make it easier to collect all the parts of a project together. Packages also affect inheritance. Protected members of classes in the package are accessible to the other members of the package. Classes outside the package see these members as private. It works a bit like the package is a super class that is extended by all the classes in the package.

Like class inheritance, packages are hierarchical. For example,

	import javax.swing.JButton;
JButton is a class in the swing package. The swing package is a package inside the javax package. It is important that package names be unique. It is possible that someone will use your package mixed in with others and there will be trouble if the names collide. One way to prevent this is to use a domain name as part of the package name.

Since domain names are unique, this should make the package unique. So, I would put my packages in a package called archie-perkins. Java expects that the package name will match a directory name. That is, I should have a folder named archie-perkins and under that, maybe a folder named cis435 to hold the packages I might have made for this class. Then under that would be the individual packages, each in its own folder. Something like this, Package folder view

Classes are part of packages. They are put in the package when they are compiled. Each class that you want to make a part of the package must have a line like this as the first non-comment line in the file.

package archie-perkins.cis435.package1;
This states the this class is part of package1, which is part of package cis435, which is part of package archie-perkins.

The class must be marked public which means that each class in the package must be in a separate file, as there can only be one public class per file. The simplest way to organize the source code for this is to put the .java files in the package1 folder. The .class files must be in the folder. If you don't want to mix the source and class files, there is a-d option on javac that can be used to separate them.

To use the classes in a package, you can either use the full name directly, which is a little tedious, or you can import the package. For example, if you didn't want to import the JButton class, you could create one like this:

	javax.swing.JButton one = new javax.swing.JButton();
Same thing with your own packages. To use myclass in package1,
	archie-perkins.cis435.package1.myclass one = new archie-perkins.cis435.package1.myclass();
or, you can just import the package like this:
	import archie-perkins.cis435.package1;
	myclass one = new myclass();
If you are using more than one class from a package, you can put a .* at the end of the import statement to include them all.

classpath

To use packages on a machine, they must be installed. Where you put them is up to you. However, they must maintain the original hierarchy. To tell the Java runtime system where to look for packages, you use the classpath variable. This is an operating system (or, more correctly, shell) level variable that you can set.

It contains a list of directories that can contain Java classes. When you use a class in a program, or include an import statement, the runtime system looks for the .class file in the directories listed in the classpath. The details of how to set the classpath are operating system dependent.

The format of the classpath is the same for all OS. Here is an example.

	.;c:\java\classes;c:\kent\cis435\classes
There is a set of directory names, separated by semi-colons. The first is a period, this indicates that the directory that the program is in should be searched first. This is why we don't have to import the other classes in the same folder. There can be as many folders listed as you need.

To save some space and to make distribution easier, you can collect packages into zip files. The zip file must contains the folder details. If it is constructed this way, you can put the zip file anywhere in the classpath and you don't have to unzip it first.

Java Archives

Just above, we saw that you could collect class files into a zip file to compress and collect them. Java provides another mechanism to do that. These are called jar files, for Java Archive. This is usually provided as a command line tool called jar. You can use this to collect all the files, or all the .class files in a folder and subfolders into a single .jar file.

As above, Java is set up so that it can search the .jar files to find what it needs, just as if the individual .class files where present. Jar files are compressed, like zip files, and so take up less room. One common use for them is with applets. You can include the .class and any other needed files into a single, compressed .jar file and thus reduce download time. One quick example. To collect all the files from my example code directory for this class, I would execute this command.

	jar cvf cis435.jar code
This produces a lot of output because of the v option. For each file, it produces a line like
adding: code/vector2/gui.class(in = 4515) (out= 2276)(deflated 49%)
adding: code/vector2/gui.java(in = 6090) (out= 2000)(deflated 67%)
The original directory was about 3.6 megabytes. The jar files was about 1.2 megabytes.