Using the JDK
Home ] Course Modules ] Browser JDK Support ] [ Using the JDK ] Assignments ] Assignment javadoc Pages ]

 

 

Using the Bare Java Software Development Kit

Caveats

The first thing I should say about using the bare Java SDK is:

Don't do it, unless you absolutely know you want to, and are comfortable with a UNIX-style command line, and other UNIX concepts.  Believe me, it's not what I would call a user-friendly environment.

I strongly recommend a Java IDE for the following reasons:

  1. Java IDEs hide a lot of the user-hostile stuff.  In particular, the class path is usually integrated in a more user-friendly manner in an IDE.  The class path is, in my experience, the biggest problem students have with Java.
  2. Java IDEs provide a more pleasant, integrated (that's the I in IDE) experience;  there's a simple to use editor, and lots of ease-of-use features.
  3. Good Java IDEs provide a visual debugger, which is light years ahead of the debugger that comes with the JSDK when it comes to the user interface.  This can be invaluable when you're stuck trying to figure out why your latest and greatest class doesn't work correctly.

However, if you really, really, insist on using the bare Java SDK, here's some help getting started:

Essential Links

One of the first things you should do when you start with Java is go to the Sun Microsystems Java web site.  Point your browser at http://java.sun.com/  

I recommend that you register.  It's free, and the benefits are enormous!  This is true whether you plan to use the bare Java SDK or not. 

This site is a rich source of lots of Java-related information.  Two places, in particular, are particularly useful:

Again, all these links are very valuable no matter how you use your Java development environment.

The Basic Java Tools

There are basically two tools you'll be using in this course:

  • javac -- the Java compiler, which translates Java source files into Java class files.
  • java -- the Java Application Launcher, which implements a Java Virtual Machine, and executes Java programs.

There are other tools, but you tend to use them a lot less.

Starting Out

Imagine you have written a Java class Foo, which looks like this:

public class Foo
{
  public static void main(String[] args)
  {
    System.out.println("Hello, Universe!");
  }
}

Remember that this source must be entered into a class with a name Foo.java (the file name must be exactly the same as the class name)

You compile this source file with the following command (assuming your current working directory is the same one as that of the .java file) :

javac Foo.java

That should work.  If you receive no errors, you should find a Foo.class file in your current working directory.

So, now, you try to run the program using the following command:

java Foo

Note that you must not say java Foo.class.  If you do, you will get:

Exception in thread "main" java.lang.NoClassDefFoundError: Foo/class

Specifying:

java Foo

will cause the class to run, and the output will be:

Hello, Universe!

Placing a Class in a Package

So far, so good.  What if we create a new class Foo2, that looks like this:

package bar;

public class Foo2
{
  public static void main(String[] args)
  {
    System.out.println("Hello, Universe!");
  }
}

The only differences are that the class has a (slightly) different name, and that it now exists inside a named package, bar.

So, let's compile it:

javac Foo2.java

That works.  Now, let's try to run it:

java Foo2

Here's what I received when I tried it:

Exception in thread "main" java.lang.NoClassDefFoundError: 
 Foo2 (wrong name: bar/Foo2)
   at java.lang.ClassLoader.defineClass0(Native Method)
   at java.lang.ClassLoader.defineClass(ClassLoader.java:537)
   at java.security.SecureClassLoader.defineClass
                                       (SecureClassLoader.java:123)
   at java.net.URLClassLoader.defineClass(URLClassLoader.java:251)
   at java.net.URLClassLoader.access$100(URLClassLoader.java:55)
   at java.net.URLClassLoader$1.run(URLClassLoader.java:194)
   at java.security.AccessController.doPrivileged(Native Method)
   at java.net.URLClassLoader.findClass(URLClassLoader.java:187)
   at java.lang.ClassLoader.loadClass(ClassLoader.java:289)
   at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:274)
   at java.lang.ClassLoader.loadClass(ClassLoader.java:235)
   at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:302)

The notorious NoClassDefFoundError !

What's wrong?

You need to fully qualify the class name with its package name when you run it using the Java Application Launcher.

java bar.Foo2

However, when I tried doing this, I received the following:

Exception in thread "main" java.lang.NoClassDefFoundError: bar/Foo2

So, this isn't the right way to handle the case of classes within explicit packages.

Using Package Names

So how are you supposed to handle things, when you use package names with classes?  Here's our Foo2 class again:

package bar;

public class Foo2
{
  public static void main(String[] args)
  {
    System.out.println("Hello, Universe!");
  }
}

First, we use the following command to compile this class:

javac -d . Foo2.java

The -d option specifies the 'destination'; the directory where the Java compiler will place the class files it produces.  In the case where the class is within a specified package, say bar, the -d option specifies a base directory;  the resulting class file will be placed in a subdirectory of the base directory which has the same name as the package name.  The "-d ." means that the destination is the current working directory (the dot means "current directory").

So, when we issue the above command, the javac compiler creates a Foo2.class file in a subdirectory bar, below the current working directory.  The compiler creates the necessary subdirectory/ies in order to create the necessary class file(s).

Now, we can try running the resulting class:

java bar.Foo2

which produces:

Hello, Universe!

This works because:

  1. We created the class file in the appropriate subdirectory, and
  2. We happen to use a default class path that works in this case.

If we were to run from a different working directory, things wouldn't work so smoothly.

Doing Things Right

Here's what you should be doing:

  1. For each Assignment (or independent project), create a directory somewhere.  For assignment 1, for example, call it, say, Ass1.  This directory will be the base directory for all files related to this project/assignment.
  2. Below Ass1, create two subdirectories, src and classes.
  3. Specify a class path that includes this classes subdirectory, and set it into the CLASSPATH environment variable.  The class path should be something like:
    set CLASSPATH="C:/Ass1/classes"
  4. When you wish to create a new Java class (say Foo2) within a package, say, bar, create its source file in a subdirectory of src, called bar, creating the bar subdirectory if necessary.
  5. When you compile a class, use the following command:
    javac -sourcepath "C:/Ass1/src" -d "C:/Ass1/classes" ClassName.java

    where 'ClassName' represents the name of the class.  Note that we're specifying that the destination of Java compilations is the Ass1/classes subdirectory. (Here, I'm using a specific place where these files will reside on a Windows system; if your location is different, change the C:/Ass1/src to a more appropriate value.)   This will result in the .class files being generated in the proper subdirectory below the classes subdirectory. 

    In addition, I'm specifying a source path (like a class path, except for source files) that points to the base src subdirectory.

    Note that the above command relies on the CLASSPATH environment variable being set up.

  6. When you run a class, use the following command:
    java packageName.ClassName

    which specifies that the class to be run lives in the specified package.

    Note that the above command relies on the CLASSPATH environment variable being set up.

Following these rules should allow you to develop a number of Java classes within one or more packages, and keep your sanity! 

Note that every IDE enforces somewhat similar rules.  It's just that you don't have to do all the hard work when you use an IDE;  they do it for you!

 

This page was last modified on 21 March, 2009