Real Java applications are made up of hundreds, or thousands, of classes. To make things manageable, the classes are grouped into packages. But when an application is being compiled and run, how does the system find all the classes? It uses classloaders to find and load the classes (and other resources like images, movies, properties files) that the program requires.
The Java runtime starts with one classloader (the bootstrap classloader) that finds classes on the local filesystem. You can create your own classloaders to find classes from other places (such as over a network connection), to compose binary classfiles on the fly, or do things while loading classes (like decrypting them, verifying digital signatures, etc.). Classloaders are chained together so that each classloader except the bootstrap loader has a parent; if a classloader can't find a class it asks its parent to find it.
Every Class object contains a reference to the ClassLoader that defined it; you'll sometimes see code that says
x.getClass().getClassLoader()
Unless you are doing fairly fancy stuff, you never have to tell a classloader to load a class; just mentioning a class is good enough. For example, the class A below refers to:
// File: ~/src/edu/lmu/cs/rtoal/scratch/A.java
package edu.lmu.cs.rtoal.scratch;
public class A {
org.bouncycastle.crypto.BlockCipher cipher =
new com.citysearch.util.crypto.HagenRedmannTwofishEngine();
void m(int x) {
java.util.List y = new java.util.ArrayList();
cipher.reset();
B b = new B();
edu.lmu.cs.rtoal.math.Complex c;
java.lang.System.out.println("okay");
}
}
// File: ~/src/edu/lmu/cs/rtoal/scratch/B.java
package edu.lmu.cs.rtoal.scratch;
public class B {}
// File: ~/src/edu/lmu/cs/rtoal/math/Complex.java
package edu.lmu.cs.rtoal.math;
public class Complex {
// Not done yet
}
So I've written classes A, B, and Complex myself, but these other classes (BlockCipher, HagenRedmannTwofishEngine, List, ArrayList, and System) already exist. But it doesn't really matter who wrote them; what matters is the full class names. A classloader needs to find:
edu.lmu.cs.rtoal.scratch.A
edu.lmu.cs.rtoal.scratch.B
edu.lmu.cs.rtoal.math.Complex
org.bouncycastle.crypto.BlockCipher
com.citysearch.util.crypto.HagenRedmannTwofishEngine
java.util.List
java.util.ArrayList
java.lang.System
But how does the bootstrap class loader find all the classes? First, it
turns the full class name into a filename — so the
first class in the list above would correspond, on a Windows
system, to
edu\lmu\cs\rtoal\scratch\A.class
(If you're compiling, and the compiler can't find that class, it will look for
edu\lmu\cs\rtoal\scratch\A.java
and compile that for you!!! How sweet.)
On almost every other system, the file names would be:
edu/lmu/cs/rtoal/scratch/A.class
(or edu/lmu/cs/rtoal/scratch/A.java)
Note: that filename is a relative path name! Relative to what? The bootstrap loader looks for it in this order:
Classpath? What's that?
A classpath is simply a list of directories and jar files. The bootstrap class loader searches a classpath when it looks for the classes (or source files) it needs, after searching the platform and extension locations.
On Windows the classpath entries are separated with semicolons; on every other platform (I think) colons are used.
Example
c:\homework\stuff.jar;c:\other\crap;c:\mylibs\junit.jar
If you requested the class a.b.C from the bootstrap classloader, and that class was not found in rt.jar or in the extensions, it would look for, in this order:
Specify the classpath when invoking a tool, for example
javac -classpath c:\homework\stuff.jar;c:\other\crap;c:\mylibs\junit.jar *.java
or, less flexibly, set the CLASSPATH environment variable (which may seem like a timesaver but can cause headaches). It's suggested you leave this environment variable unset and use a specific classpath when you invoke a tool. If you really must know about this variable, consult Sun's online docs.
See Sun's documentation on How Classes are Found.
Developers should be familiar with all three main approaches to building applications
Everything you need to know is in Sun's tool documentation.
The defacto standard application for building Java applications is Ant.
Once you understand how to build applications the hard way, you're ready to fire up an IDE and use a nice tool to construct classpaths for your projects. Some IDEs just let you drag and drop jar files and directories into a window. However you do it, you need to understand what a classpath is.
There are three main ways to distribute a Java application:
Once you start writing your own classloaders or you start deploying applications with multiple classloaders, you'll probably run into the case where a single class file is loaded by each classloader. Your application will think there are two distinct classes, and, well, some confusing things may start to happen. Just be aware.