Presentation is loading. Please wait.

Presentation is loading. Please wait.

Dynamic Code Generation in Java. Class Loading Class loading is the process of transforming a byte code (e.g., a.class file) into a Java class A Java.

Similar presentations


Presentation on theme: "Dynamic Code Generation in Java. Class Loading Class loading is the process of transforming a byte code (e.g., a.class file) into a Java class A Java."— Presentation transcript:

1 Dynamic Code Generation in Java

2 Class Loading Class loading is the process of transforming a byte code (e.g., a.class file) into a Java class A Java class can be loaded dynamically (i.e., during runtime) The class is then represented by an object of class Class You can use the method Class.forName("name") to generate a Class object, given its name

3 Dynamic Code Invocation Using dynamic class loading, we can dynamically generate a.class file, load it, instantiate it ( class.newInstance() ), and invoke its methods Hence, we can dynamically write and invoke programs How can we access a method of an object, if we do not know its type on compile time? One way is to implement a known interface

4 Our Example In the following example, we will invoke the method run() of a dynamically created object of type Base public interface Base { public void run(); }

5 An Example public class Invoker { public static void main(String[] argv) throws Exception { String code = "public class C implements Base {\n" + " public void run() {\n" + " System.out.println(\"++++++++++\");\n" + " }}"; createClass(code); Class classB = Class.forName("C"); Base b = (Base)classB.newInstance(); b.run(); }

6 An Example public static void createClass(String code) throws Exception { OutputStream os = new FileOutputStream(new File("C.java")); os.write(code.getBytes()); os.close(); Process p = Runtime.getRuntime(). exec("javac -classpath. C.java"); p.waitFor(); }

7 The Whole Process

8 Assumptions The later code assumes the following: The command javac is known to the System -e.g., the javac executable is in the PATH variable The directory ". " is included in the class path of Java -Hence, Class.forName("C") will find that class

9 Class Reloading String code1 = "public class C implements Base {\n" + "public void run() {\n" + "System.out.println(\"++++++++++\");\n" + "}}"; String code2 = "public class C implements Base {\n" + "public void run() {\n" + "System.out.println(\"----------\");\n" + "}}"; createClass(code1); ((Base)Class.forName("C").newInstance()).run(); createClass(code2); ((Base)Class.forName("C").newInstance()).run(); What is the problem here?

10 The System Class Loader Java classes are loaded using a class loader Class.forName(name) usually invokes loadClass(name) of the system class loader The system class loader can be accessed by ClassLoader.getSystemClassLoader() Hence, a class can equivalently be loaded by ClassLoader.getSystemClassLoader().loadClass(name)

11 Bootstrap Class Loader Another class loader that exists in the system is the bootstrap class loader This class loader is built in with the JVM This class is used to load built-in JVM classes, and is used early in the runtime startup Classes that you write are usually loaded by the system class loader, and not by the bootstrap one

12 Class Loading Method Every class loader has a parent class loader, which could be null By default, class loading is done as follows: -check if a class with the given name has already been loaded by the same class loader -check if the parent can load the class If parent is null, use the bootstrap class loader -invoke the method findClass("class-name") When you load a class, all referenced classes are recursively loaded by the same class loader

13 Back to our Example So what should we do to reload a class? Answer: -use a new class loader to load the class C -make sure that this loader does not have a parent capable of loading class C For that, we can obtain a ClassLoader object by instantiating java.net.URLClassLoader

14 URLClassLoader A URLClassLoader has an array of URLs (“http://...”, “file://...”, etc.) of either directories or JAR files, and it loads classes from the resources of the URLs Constructor: URLClassLoader(URLs,parent) We will set the URLs to contain only the URL of “.”, and the parent to be null

15 Fixed(?) Example URL[] urls = {new File(".").toURL()}; createClass(code1); ClassLoader loader = new URLClassLoader(urls,null); Class classB = loader.loadClass("C"); ((Base)classB.newInstance()).run(); createClass(code1); loader = new URLClassLoader(urls,null); classB = loader.loadClass("C"); ((Base)classB.newInstance()).run(); What is the problem here?

16 A Problem The interface Base is also being loaded by the new class loaders -But the system already has one interface called Base Each newly created interface is considered as a unique interface Hence, it is impossible to cast C to Base

17 Solutions Solution 1: to invoke run(), use reflection rather than down casting Solution 2: use the system class loader as a parent, but call findClass() directly, instead of loadClass() -problem: this method is protected -Solution? -Solution 2 is given in Exercise 3

18 Fixed(!) Example URL[] urls = {new File(".").toURL()}; createClass(code1); ClassLoader loader = new URLClassLoader(urls,null); Class classB = loader.loadClass("C"); Method runMethod = classB.getMethod("run", null); runMethod.invoke(classB.newInstance(),null); createClass(code2); classB = new URLClassLoader(urls,null).loadClass("C"); classB.getMethod("run",null).invoke(classB.newInstance(),null);


Download ppt "Dynamic Code Generation in Java. Class Loading Class loading is the process of transforming a byte code (e.g., a.class file) into a Java class A Java."

Similar presentations


Ads by Google