Java packages and understanding CLASSPATH environment variable and fixing NoClassDefFoundError and ClassNotFoundException exceptions
Q. What are the usages of Java packages?
A. It helps resolve naming conflicts when different packages have classes with the same names. This also helps you organize files within your project. For example: java.io package does something related to I/O and java.net package does something to do with network and so on. If we tend to put all .java files into a single package, as the project gets bigger, then it would become a nightmare to manage all your files.
You can create a package as follows with package keyword, which is the first keyword in any Java program followed by import statements. The java.lang package is imported implicitly by default and all the other packages must be explicitly imported.
package com.xyz.client ; import java.io.File; import java.net.URL;
Q. What do you need to do to run a class with a main( ) method in a package?
A. Example: Say, you have a class named “Pet” in a project folder “c:\myProject” and package named com.xyz.client, will you be able to compile and run it as it is?
package com.xyz.client; public class Pet { public static void main(String[] args) { System.out.println("I am found in the classpath"); } }
Q. Can you now run the above Pet class as c:\myProject> java com.xyz.client.Pet?
A. No. You will get the following exception: “Exception in thread "main" java.lang.NoClassDefFoundError: com/xyz/client/Pet”. You need to set the classpath. How can you do that? One of the following ways.
- 1. Set the operating system CLASSPATH environment variable to have the project folder “c:\myProject”. [Shown in the above diagram as the System –classpath class loader].
- 2. Set the operating system CLASSPATH environment variable to have a jar file “c:/myProject/client.jar”, which has the Pet.class file in it. [Shown in the above diagram as the System –classpath class loader].
- 3. Run it with –cp or –classpath option as shown below:
c:\>java –cp c:/myProject com.xyz.client.Pet
OR
c:\>java -classpath c:/myProject/client.jar com.xyz.client.Pet
Q. Are 2 same objects loaded by 2 different class loaders equal?
A. No. Two objects loaded by different class loaders are never equal even if they carry the same values, which means a class is uniquely identified in the context of the associated class loader. This applies to singletons too, where each class loader will have its own singleton.
Q. What are the different ways to create new objects in Java?
A. There are 2 ways to create new objects in Java.
1. Static
2. Dynamic
1. Static loading
Classes are statically loaded with Java’s “new” operator.
class MyClass { public static void main(String args[]) { Car c = new Car(); } }
A NoClassDefFoundException is thrown if a class is referenced with Java’s “new” operator (i.e. static loading) but the run time system cannot find the referenced class.
2. Dynamic loading
Dynamic loading is a technique for programmatically invoking the functions of a class loader at run time. Let us look at how to load classes dynamically.
Class.forName (String className); //static method which returns a Class
The above static method returns the class object associated with the class name. The string className can be supplied dynamically at run time. Unlike the static loading, the dynamic loading will decide whether to load the class Car or the class Jeep at run time based on a properties file and/or other run time conditions. Once the class is dynamically loaded, the following method returns an instance of the loaded class. It’s just like creating a class object with no arguments.
class.newInstance( ); //A non-static method, which creates an instance of a class
Creating an instance of a Jeep class dynamically
Jeep myJeep = null ; //myClassName should be read from a .properties file or a Constants class. // stay away from hard coding values in your program. CO String myClassName = "au.com.Jeep" ; Class vehicleClass = Class.forName(myClassName) ; myJeep = (Jeep) vehicleClass.newInstance(); myJeep.setFuelCapacity(50);
A ClassNotFoundException is thrown when an application tries to load in a class through its string name using the following methods but no definition for the class with the specified name could be found:
- The forName(..) method in class - Class.
- The findSystemClass(..) method in class - ClassLoader.
- The loadClass(..) method in class - ClassLoader.
Q. How will you dynamically load class files that are not in the classpath?
A.
File file = new File("c:\\myProject\\"); try { // Convert File to a URL URL url = file.toURL(); // file:/c:/myProject/ URL[] urls = new URL[]{url}; // Create a new class loader with the directory ClassLoader cl = new URLClassLoader(urls); // Load in the class; Pet.class should be located in // the directory file:/c:/myProject/com/xyz/client Class cls = cl.loadClass("com.xyz.client.Pet"); } catch (MalformedURLException e) { e.printStacktrace(); } catch (ClassNotFoundException e) { e.printStacktrace(); }
The above example make use of the URLClassLoader and the example below makes use of the getSystemClassLoader( ) method
Pet obj = (Pet) ClassLoader.getSystemClassLoader().loadClass("com.xyz.client.Pet").newInstance(); obj.method();
You may also like:
- Debugging Java EE Class loading issues
- Troubleshooting Java EE classloader issues -- JBoss example
- Troubleshooting Java classloader issues -- Weblogic example
Labels: Class loader, Core Java
0 Comments:
Post a Comment
Subscribe to Post Comments [Atom]
<< Home