In some
situations, you may want to load two versions of same class, you can do that by
using class loaders.
As you see
above image, class loader 1 loads version 1 of class, whereas class loader 2
loads version 2 of class.
Class.forName
public
static Class<?> forName(String name,boolean initialize, ClassLoader
loader)
forName
method loads given class using the classloader specified by user.
Below
step-by-step procedure helps you to develop an application that loads two
versions of same class.
Step 1:
Create version1.jar
file.
Define
ProductInfo class by following below directory structure.
$tree . └── com └── sample └── app └── model └── ProductInfo.java 4 directories, 1 file
ProductInfo.java
package com.sample.app.model; public class ProductInfo { static { System.out.println("Loading version 1 of the class"); } public String toString() { return "Version 1 of the class is loaded"; } }
Compile
ProductInfo.java by executing below command.
javac
com/sample/app/model/ProductInfo.java
$javac com/sample/app/model/ProductInfo.java $ $tree . └── com └── sample └── app └── model ├── ProductInfo.class └── ProductInfo.java 4 directories, 2 file
Execute
below command to generate version1.jar file.
jar -cvf
version1.jar *
$jar -cvf version1.jar * added manifest adding: com/(in = 0) (out= 0)(stored 0%) adding: com/sample/(in = 0) (out= 0)(stored 0%) adding: com/sample/app/(in = 0) (out= 0)(stored 0%) adding: com/sample/app/model/(in = 0) (out= 0)(stored 0%) adding: com/sample/app/model/ProductInfo.class(in = 559) (out= 357)(deflated 36%) adding: com/sample/app/model/ProductInfo.java(in = 211) (out= 151)(deflated 28%) $ $tree . ├── com │ └── sample │ └── app │ └── model │ ├── ProductInfo.class │ └── ProductInfo.java └── version1.jar 4 directories, 3 files
Step 2:
Create version2.jar
file.
Update
productInfo.java file like below.
package com.sample.app.model; public class ProductInfo { static { System.out.println("Loading version 2 of the class"); } public String toString() { return "Version 2 of the class is loaded"; } }
Compile
ProductInfo.java.
Create version2.jar
by executing below command.
jar -cvf
version2.jar *
Step 3:
Create App.java file
that loads the classes using URLClassLoader.
Below
snippet loads the ProductInfo class from version1.jar file.
URL url1 =
new URL("file:/Users/krishna/Documents/TechnicalDocuments/Java/examples/classloading/version1.jar");
URLClassLoader
classLoader1 = new URLClassLoader(new URL[] { url1 });
Class
clazz1 = Class.forName("com.sample.app.model.ProductInfo", true,
classLoader1);
Below
snippet loads the ProductInfo class from version2.jar file.
URL url2 =
new
URL("file:/Users/krishna/Documents/TechnicalDocuments/Java/examples/classloading/version2.jar");
URLClassLoader
classLoader2 = new URLClassLoader(new URL[] { url2 });
Class
clazz2 = Class.forName("com.sample.app.model.ProductInfo", true,
classLoader2);
App.java
import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; public class App { public static void main(String args[]) throws MalformedURLException, ClassNotFoundException, InstantiationException, IllegalAccessException { URL url1 = new URL( "file:/Users/krishna/Documents/TechnicalDocuments/Java/examples/classloading/version1.jar"); URLClassLoader classLoader1 = new URLClassLoader(new URL[] { url1 }); URL url2 = new URL( "file:/Users/krishna/Documents/TechnicalDocuments/Java/examples/classloading/version2.jar"); URLClassLoader classLoader2 = new URLClassLoader(new URL[] { url2 }); Class clazz1 = Class.forName("com.sample.app.model.ProductInfo", true, classLoader1); Class clazz2 = Class.forName("com.sample.app.model.ProductInfo", true, classLoader2); Object obj1 = clazz1.newInstance(); Object obj2 = clazz1.newInstance(); System.out.println(obj1); System.out.println(obj2); } }
Compile
and run App.java, you can see below messages in console.
Loading
version 1 of the class
Loading
version 2 of the class
Version 1
of the class is loaded
Version 1
of the class is loaded
No comments:
Post a Comment