Tuesday, March 27, 2007

Putting a Java pogram to sleep

For a good night's sleep wear comfortable loose clothes, do not consume coffee or tea after 6:00 PM, and read something relaxing before going to bed. Old hat.

ok that's cool, but what if you want to put your Java Thread to sleep? Before Java SE 5, the most common way to put threads to sleep was by calling the sleep() method.


System.out.println("Sleeping for 150 ms");
Thread.sleep(150);
System.out.println("Sleeping for 2 seconds");
Thread.sleep(1000);
System.out.println("Sleeping for 50 nanoseconds");
Thread.sleep(050);
Java2html

 

 

The sleep() method takes a long parameter that  represents the milliseconds we want the thread to sleep. If the time we want our thread to sleep can be easily represented in ms, then this method works out well, but if we want the thread to sleep for some seconds then we have to perform the conversion manually. Even worse, if we want the thread to sleep for nanoseconds, then we have to use the confusing sleep() method that takes 2 parameters as shown in the code above. Such code is not very readable.

Java SE 5 gives us better readability in the form of the TimeUnit class. TimeUnit is an enum that has defines constants for DAYS, HOURS, MICROSECONDS, MILLISECONDS, MINUTES, NANOSECONDS,  and SECONDS. TimeUnit also has a sleep() method which we can call on the appropriate constant to put the thread to sleep for the number of specified units.


System.out.println("Sleeping for 150 ms");
TimeUnit.MILLISECONDS.sleep(150);
System.out.println("Sleeping for 2 seconds");
TimeUnit.SECONDS.sleep(2);
System.out.println("Sleeping for 50 nanoseconds");
TimeUnit.NANOSECONDS.sleep(50);
Java2html

 

 

Besides this TimeUnit also provides methods for converting values among different time units. Using the TimeUnit enum is definetely preffered over using Thread.sleep() if you are using Java SE 5.

There is one line in the above code samples that I am not sure will work correctly. By "work correctly" I do not mean it will cause a compiler error, but it may not work as promised. Can anyone point out which line?

Discuss this post in the learning forum.



Note: This text was originally posted on my earlier blog at http://www.adaptivelearningonline.net

Friday, March 23, 2007

Security and the Java classloader

The Java classloader plays an important part in the overall security of a Java application.

The classloader works along with the SecurityManager and the Access Controller to make a Java system secure. The classloader is important because it is the entity that first loads the classes. The classloader knows the codebase from where the code was loaded, and if the code was signed. The classloader works in three ways to help make a Java system secure:

  1. It helps the JVM to maintain the integrity of namespaces.
  2. It maps permissions with each class. The permissions associated with every class are also known as the protection domain of the class. This mapping helps the access controller determine which classes have which permissions.
  3. It ensures that code which accesses or defines classes has the appropriate permissions to do so. The classloader works in conjunction with the SecurityManager to enforce this.
Each of these topics are fairly long, and I will not go into intricate details. I will however explain the first topic briefly below.

Definition of namespaces:
We all know that each class in Java is uniquely identified by it's package name. But that's not all. In reality a class is uniquely identified by it's fully qualified name and the classloader that loaded it. Can you imagine why this is needed? It is needed to prevent the integrity of code that is running in Applets. Assume you load Applets from www.sun.com and some malicious website in your browser. If the malicious website uses package names such as com.sun.*, then it is possible that their classes might be used when the Applet from www.sun.com tries to invoke a class, thus causing damage. However this will not happen because classes are unique to the package name and the classloader that loaded them. A different instance of the classloader is used to load the Applet from www.sun.com and the Applet from the malicious website. Hence even if both of them use classes with the same package names, unique instances of these classes will be created for both the Applets amd they will not be able to access each other's classes.

Mapping permissions of classes:
We can configure the Java policy file to restrict or allow certain actions to code loaded from a particular codebase. We can also grant certain priviledges to code that has been signed by a trusted entity. For example we might want to provide I/O access to Applet code that has been signed by sun.com. It is the classloader that helps in managing this information. The classloader works in conjunction with the security manager and the access controller to enforce the permissions.
 
You might want to read the links below to better understand how the classloader works.

References:


Notes: This text was originally posted on my earlier blog at http://www.adaptivelearningonline.net

Friday, March 16, 2007

Loading classes

Now that we have understood how the Classloader locates classes, what exactly does loading a class mean? What happens when a class is loaded?

Loading refers to the process of finding the binary form of a class or interface type with a particular name, perhaps by computing it on the fly, but more typically by retrieving a binary representation previously computed from source code by a compiler, and constructing, from that binary form, a Class object to represent the class or interface.

The binary format of a class or interface is normally the class file format described in The Java Virtual Machine Specification, but other formats are possible, provided they meet the specified requirements. The method defineClass of class ClassLoader may be used to construct Class objects from binary representations in the class file format.

The loading process is implemented by the class ClassLoader and its subclasses. Different subclasses of ClassLoader may implement different loading policies. In particular, a class loader may cache binary representations of classes and interfaces, prefetch them based on expected usage, or load a group of related classes together. These activities may not be completely transparent to a running application if, for example, a newly compiled version of a class is not found because an older version is cached by a class loader. It is the responsibility of a class loader, however, to reflect loading errors only at points in the program they could have arisen without prefetching or group loading.

If an error occurs during class loading, then an instance of one of the following subclasses of class LinkageError will be thrown at any point in the program that (directly or indirectly) uses the type:

  • ClassCircularityError: A class or interface could not be loaded because it would be its own superclass or superinterface.

  • ClassFormatError: The binary data that purports to specify a requested compiled class or interface is malformed.

  • NoClassDefFoundError: No definition for a requested class or interface could be found by the relevant class loader.


The above passage is an excerpt from The Java Language Specification.

What it means is, when the JVM needs a class, it is the responsibility of the ClassLoader to locate and loading it. The ClassLoader locates the class file as discussed earlier and creates a 'java.lang.Class' object that represents the class. So for example, when the String class is loaded, a java.lang.Class instance is created to represent the String class. Class instances are created for every class and NOT for every instance of the class. Even if we create 1000 String instances, only one instance of Class will be created to represent the String class. Think of the class Class as a blueprint of the class that was loaded. It contains the name of the class, it's superclasses, implemented interfaces, attributes, and methods.

When the JVM has to instantiate a Student object, it will first delegate the task of loading that object to the ClassLoader. The ClassLoader finds the file Student.class, reads it's contents and creates an object of type java.lang.Class, which represents the Student class. This object is handed over to the JVM, which uses it to create instances of type Student.

Till now we have seen that the ClassLoader locates a class by finding it in the local file system using the CLASSPATH environment variable. This is how classes are loaded most of the time, but it is not the only way. Classes can be loaded from the network over a TCP/IP socket (this is how classes are loaded in an Applet), by using a custom ClassLoader. Custom ClassLoaders can also be used for special checks, like the verification of digital signature of classes that are loaded. You can use, or write your own custom ClassLoader to load classes in an unconventional manner.

The ClassLoader  performs several checks on the class that is loaded. We will understand them in greater detail in the next post.



Note: This text was originally posted on my earlier blog at http://www.adaptivelearningonline.net

Saturday, March 10, 2007

The Java Classloader #2

Now that we understand the importance of dynamic linking, assume that you are running a dynamically linked C++ program which needs to use a class that is in an external library. The runtime locates the external library using the PATH environment variable.

Java programs do not use the PATH environment variable to locate classes, they use the CLASSPATH variable instead. CLASSPATH contains a list of directories, zip files or jar files. You are probably thinking, why Java does not use PATH? Why did it invent another environment variable, the CLASSPATH? One reason why Java did ot choose to use the PATH variable, is because PATH already contains entries needed by other executables. Using PATH may slow down the system, because it will have to process extra entries. OK, so if that convinces you, let's have a look at what the CLASSPATH contains. The CLASSPATH contains a list of directories, which contain class files that will be needed by the Java runtime (Note: Core Java classes like the String class are found automatically by the runtime. We do not need to add entries in the CLASSPATH to locate them). Zip files and jar files are also allowed because if you think about it, they are nothing but archived and compressed directories.

Consider a scenario where we are running a Java based Student Registration software. During execution some class tries to instantiate the Student class. Since a Java program is not distributed as one large executable file, the JVM needs to locate and load the Student class. The JVM iterates through all the entries in the CLASSPATH and searches for the class file in every entry. If the class cannot be found, the JVM throws a ClassNotFoundException. If a classfile exists in a directory or jar file not listed in the CLASSPATH, then as far as the JVM is concerned, it does not exist. The responsibility of locating and loading classes is assigned to the Java Classloader.

There are a few holes in this approach. Can you find them? What if an external library we are using also has a Student class. Which class will the Classloader load? Our Student class or the Student class from the external library? Is there an unambiguous way to determine the right class? Well, we asked the JVM to load a class called Student, it has no way of knowing which one of the multiple Student classes in the CLASSPATH is the right class. Clearly we must have a unique attribute that differentiates all the Student classes. This unique attribute is called a namespace which is represented as a package name in Java. Every Java class must exist in a namespace which is specified using the package keyword. Even classes that do not belong to any specific package, belong to the default package.

The code below shows how we can create a Student class which belongs to the 'edu.scit.studentreg' package.

package edu.scit.studentreg;

public class Student {

}

The use of packages differentiates this class from another class which is also called Student but belongs to the namespace 'com.oracle.studentreg'.

package com.oracle.studentreg;

public class Student {

}

Now when we want to instantiate a Student class we will instantiate it by using the fully qualified name of the class.

edu.scit.studentreg.Student s1 = new edu.scit.studentreg.Student();

or

com.oracle.studentreg.Student s2 = new com.oracle.studentreg.Student();

Because we have used the fully qualified class name, the Classloader knows exactly which Student class we are reffering to. But wait... a Student class is created in a file called Student.class. We do not use the package name in the name of the file. How does the Classloader know which class file is the right one? Even though the class file contains the package name, searching for Student.class in every directory and subdirectory in the CLASSPATH, to determine if it contains the right package name is a very time consuming process. We need a better way of organizing class files, so the JVM can locate them quickly. The convention used is to match the directory heirarchy in which a class file is put with the package name of the class. Let us understand this concept with an example we have used above. Where should we put the class edu.scit.studentreg.Student? First of all we determine a base directory in which we will put this and many other classes. If we decide to put our classes in c:\scit\classes, then we have to follow the convention relative to c:\scit\classes. We must create a directory called 'edu' (in c:\scit\classes) then we create a directory called 'scit' in 'edu' and a directory called 'studentreg' in 'scit'. The file Student.class is placed inside the 'studentreg' directory. What do you think should go in the CLASSPATH? c:\scit\classes or c:\scit\classes\edu\scit\studentreg? We put c:\scit\classes.

When the Classloader needs to locate the class edu.scit.studentreg.Student, it will look at the first entry in the classpath. Suppose it is c:\scit\classes. The JVM will now try to locate the class by zeroing in to the appropriate location based on the package name of the class. First it looks for a directory edu in c:\scit\classes, if it finds the directory then it looks for scit inside edu and studentreg inside scit. Once in the studentreg directory it looks for a file called Student.class. If found the file is loaded, othewise the next entry in the classpath is searched. If the file is not found in any of the directories specified in the classpath, then a ClassNotFoundExceptin is thrown.

This is how the Classloader locates and loads class files.

Even if you have understood how the Classloader loactes class files, I would like to suggest that you practice a couple of times of understand the concept better. To best understand these concepts, I strongly recommend that you work with Notepad and the command line.

  1. Create any class and associate it with the package example.code , and compile the class. Ensure that the Java as well as the class file exist in a proper directory heirarchy. Add the appropriate directory to the CLASSPATH and run the program from a totally different directory.
  2. Change the location of the class file and run the program.
  3. Remove the directory from the CLASSPATH, and run the program from the parent directory of the directory which you had put in your CLASSPATH. Does the program run? If not, try removing all CLASSPATH entries and run the program again.

Please note, while removing CLASSPATH entries, do not remove them from the environment of the operating system. Each command prompt gets the CLASSPATH that is set for that user, however, we can modify the CLASSPATH of only that command prompt without affecting the OS's environment.

In the next post, we will look at some more nuances of the Classloader.



Notes: This text was originally posted on my earlier blog at http://www.adaptivelearningonline.net

Monday, March 05, 2007

The Java classloader #1

This week I am starting a series on the Java classloader. Before we start talking about the classloader here's a little foundation.

If you have programmed with C++, you will remember there are two ways of compiling and linking programs.

  1. Static

  2. Dynamic

Any large software consists of many classes and dependencies on external libraries.

Statically compiling a program means creating one large executable file containing all the classes and dependencies. Since all that it needs is bundled in one file which is loaded when the program starts, such a program does not need to locate any files when running. However, because statically linked programs have a very large footprint, this approach is not favored, and an approach known as dynamic linking is used.

The output of a dynamically compiled program is an executable file containing the core program, and many libraries files. When the program starts running only the main executable is loaded in memory. Dependencies are loaded as and when required. Some of these dependencies may be distributed with the software while others may already exist in the underlying operating system, and the program simply expects them to be there. When the program needs to invoke a class that is in an external library, the runtime locates the library and loads the class.

Java uses an approach closer to the latter. In fact Java programs can NEVER be statically linked (unless you compile them into statically linked native code). Software written in Java is distributed as a bundle of class or jar files. When the program is executing, the JVM has to find, load, and invoke methods of various classes. All the classes are not loaded at once, instead they are located and loaded as they are required. The task of loading these class files is the responsiility of the Java classloader.

We will discuss  the Java classloader in greater detail in the next post.

 



Note: This text was originally posted on my earlier blog at http://www.adaptivelearningonline.net