A ClassPath example

To demonstrate how the ClassPath concept works, let's move one of the class files to a different directory. Conceptually, this is the same as using an external dependency, which by convention, is also stored in a different directory than the project's classes. Follow this procedure:

  • In your project directory, which contains the src and bin directories, create a new lib directory
  • Inside the new lib directory, create the com\example\app\model subdirectories
  • Move the ModelFoo.class file to the model subdirectory you created earlier
  • For clarity, remove the empty bin\com\example\app\model directory

The directory structure should now look like:

In your Command Prompt or Terminal Window, change the directory to the project's bin subdirectory and try to run the program again:

java com.example.app.Controller

You should now see a Java stack trace. Get used to this; you'll be seeing errors such as these a lot in your JVM development career. On my machine, it looked like this (cut for brevity):

Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.NoClassDefFoundError: com/example/app/model/ModelFoo
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Unknown Source)
at java.lang.Class.privateGetMethodRecursive(Unknown Source)
at java.lang.Class.getMethod0(Unknown Source)
...

Now tell the java command that it must look for the classes referenced in the code, both in the current directory and the lib directory (which is one level above the current bin directory), by passing the -cp option to set the ClassPath:

java -cp ".;..\lib" com.example.app.Controller

When looking for a class, the JVM first looks in the current directory and, if it is unable to find the class there, it tries to find the class in the ..lib subdirectory. Note that the -cp option and value must be specified before the class name; otherwise, they will be passed to the main function argument's String array parameter instead of the java command.