Table of Contents
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:
- 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.
- 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.
- 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 Java web site. Point your browser at https://java.com/ . Here you can download the latest version of the Java SDK (Software Development Kit).
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:
- The Java Tutorial. Start by clicking on the Your First Cup of Java link, and follow the instructions to learn how to start on your platform of choice.
- The JDK documentation. This is a pure reference, but it’s going to be where you go for a lot of detailed information about Java.
Again, all these links are very valuable no matter how you use your Java development environment.
The Basic Java Tools
Here’s a taste of what it’s like to use the bare JDK…
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 file with a name Foo.java (the file name must be exactly the same as the class name, case-sensitive).
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:
- We created the class file in the appropriate subdirectory, and
- 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:
- 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. - Below
Ass1, create two subdirectories,srcandclasses. - Specify a class path that includes this classes subdirectory, and set it into the CLASSPATH environment variable. In Microsoft Windows, for example, the class path should be something like:
set CLASSPATH=”C:/Ass1/classes” - When you wish to create a new Java class (say
Foo2) within a package, say,bar, create its source file in a subdirectory ofsrc, calledbar, creating thebarsubdirectory if necessary. - 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 theAss1/classessubdirectory. (Here, I’m using a specific place where these files will reside on a Windows system; if your location is different, change theC:/Ass1/srcto a more appropriate value.) This will result in the.classfiles being generated in the proper subdirectory below theclassessubdirectory. In addition, I’m specifying a source path (like a class path, except for source files) that points to the basesrcsubdirectory. Note that the above command relies on the CLASSPATH environment variable being set up. - 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!
Sure, it takes a little effort to learn the essentials of the IDE, but you get that investment back in spades over many projects!
