Follow Techotopia on Twitter

On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
System/Network Admin
Programming
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Databases
Mail Systems
openSolaris
Eclipse Documentation
Techotopia.com
Virtuatopia.com

How To Guides
Virtualization
General System Admin
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Windows
Problem Solutions

  




 

 

Thinking in Java
Prev Contents / Index Next

Creating unique package names

You might observe that, since a package never really gets “packaged” into a single file, a package could be made up of many .class files, and things could get a bit cluttered. To prevent this, a logical thing to do is to place all the .class files for a particular package into a single directory; that is, use the hierarchical file structure of the operating system to your advantage. This is one way that Java references the problem of clutter; you’ll see the other way later when the jar utility is introduced.

Collecting the package files into a single subdirectory solves two other problems: creating unique package names, and finding those classes that might be buried in a directory structure someplace. This is accomplished, as was introduced in Chapter 2, by encoding the path of the location of the .class file into the name of the package. By convention, the first part of the package name is the reversed Internet domain name of the creator of the class. Since Internet domain names are guaranteed to be unique, if you follow this convention, your package name will be unique and you’ll never have a name clash. (That is, until you lose the domain name to someone else who starts writing Java code with the same path names as you did.) Of course, if you don’t have your own domain name, then you must fabricate an unlikely combination (such as your first and last name) to create unique package names. If you’ve decided to start publishing Java code, it’s worth the relatively small effort to get a domain name.

The second part of this trick is resolving the package name into a directory on your machine, so when the Java program runs and it needs to load the .class file (which it does dynamically, at the point in the program where it needs to create an object of that particular class, or the first time you access a static member of the class), it can locate the directory where the .class file resides.

The Java interpreter proceeds as follows. First, it finds the environment variable CLASSPATH[27] (set via the operating system, and sometimes by the installation program that installs Java or a Java-based tool on your machine). CLASSPATH contains one or more directories that are used as roots in a search for .class files. Starting at that root, the interpreter will take the package name and replace each dot with a slash to generate a path name from the CLASSPATH root (so package foo.bar.baz becomes foo\bar\baz or foo/bar/baz or possibly something else, depending on your operating system). This is then concatenated to the various entries in the CLASSPATH. That’s where it looks for the .class file with the name corresponding to the class you’re trying to create. (It also searches some standard directories relative to where the Java interpreter resides).

To understand this, consider my domain name, which is bruceeckel.com. By reversing this, com.bruceeckel establishes my unique global name for my classes. (The com, edu, org, etc., extensions were formerly capitalized in Java packages, but this was changed in Java 2 so the entire package name is lowercase.) I can further subdivide this by deciding that I want to create a library named simple, so I’ll end up with a package name:

package com.bruceeckel.simple;


Now this package name can be used as an umbrella name space for the following two files:

//: com:bruceeckel:simple:Vector.java
// Creating a package.
package com.bruceeckel.simple;

public class Vector {
  public Vector() {
    System.out.println("com.bruceeckel.simple.Vector");
  }
} ///:~


When you create your own packages, you’ll discover that the package statement must be the first noncomment code in the file. The second file looks much the same:

//: com:bruceeckel:simple:List.java
// Creating a package.
package com.bruceeckel.simple;

public class List {
  public List() {
    System.out.println("com.bruceeckel.simple.List");
  }
} ///:~


Both of these files are placed in the subdirectory on my system:

C:\DOC\JavaT\com\bruceeckel\simple


If you walk back through this, you can see the package name com.bruceeckel.simple, but what about the first portion of the path? That’s taken care of in the CLASSPATH environment variable, which is, on my machine:

CLASSPATH=.;D:\JAVA\LIB;C:\DOC\JavaT


You can see that the CLASSPATH can contain a number of alternative search paths.

There’s a variation when using JAR files, however. You must put the name of the JAR file in the classpath, not just the path where it’s located. So for a JAR named grape.jar your classpath would include:

CLASSPATH=.;D:\JAVA\LIB;C:\flavors\grape.jar


Once the classpath is set up properly, the following file can be placed in any directory:

//: c05:LibTest.java
// Uses the library.
import com.bruceeckel.simpletest.*;
import com.bruceeckel.simple.*;

public class LibTest {
  static Test monitor = new Test();
  public static void main(String[] args) {
    Vector v = new Vector();
    List l = new List();
    monitor.expect(new String[] {
      "com.bruceeckel.simple.Vector",
      "com.bruceeckel.simple.List"
    });
  }
} ///:~


When the compiler encounters the import statement for the simple library, it begins searching at the directories specified by CLASSPATH, looking for subdirectory com\bruceeckel\simple, then seeking the compiled files of the appropriate names (Vector.class for Vector, and List.class for List). Note that both the classes and the desired methods in Vector and List must be public.

Setting the CLASSPATH has been such a trial for beginning Java users (it was for me, when I started) that Sun made the JDK in Java 2 a bit smarter. You’ll find that when you install it, even if you don’t set the CLASSPATH, you’ll be able to compile and run basic Java programs. To compile and run the source-code package for this book (available at www.BruceEckel.com), however, you will need to add the base directory of the book’s code tree to your CLASSPATH.

Collisions

What happens if two libraries are imported via ‘*’ and they include the same names? For example, suppose a program does this:

import com.bruceeckel.simple.*;
import java.util.*;


Since java.util.* also contains a Vector class, this causes a potential collision. However, as long as you don’t write the code that actually causes the collision, everything is OK—this is good, because otherwise you might end up doing a lot of typing to prevent collisions that would never happen.

The collision does occur if you now try to make a Vector:

Vector v = new Vector();


Which Vector class does this refer to? The compiler can’t know, and the reader can’t know either. So the compiler complains and forces you to be explicit. If I want the standard Java Vector, for example, I must say:

java.util.Vector v = new java.util.Vector();


Since this (along with the CLASSPATH) completely specifies the location of that Vector, there’s no need for the import java.util.* statement unless I’m using something else from java.util.
Thinking in Java
Prev Contents / Index Next


 
 
   Reproduced courtesy of Bruce Eckel, MindView, Inc. Design by Interspire