zaterdag 21 december 2013

Dynamically load jar file in systemclassloader

This example is showing how to download a jar file into the jvm and use the classes in that jar file. First we create a jar file with a Hello.class in it. The Hello.class does some logging when its get called. After creating the jar file we set up a HTTP server which alows us to download the jar file from a url. The next step is creating a Jython application which after is start will download the jar, put in into the system class loader and run the Hello.class. 1) Creating the Hello.class. This is a very basic class, which is printing if a method is called.
package nl.sysgarden;

public class Hello {
 public Hello() {
  System.out.println("Hello.function.Constuctor");
 }
 public static void main (String[] args){
  System.out.println("Hello.function.main");
 }
 public void p1(){
  System.out.println("Hello.funtion.p1");
 }
}
2) Creating a jar file: After compile 'javac nl/sysgarden/Hello.java' we put the class in the jar file httpjartest.jar
user$ jar cvf httpjartest.jar nl/sysgarden/Hello.*
added manifest
adding: nl/sysgarden/Hello.class(in = 540) (out= 343)(deflated 36%)
adding: nl/sysgarden/Hello.java(in = 272) (out= 146)(deflated 46%)
Testing the jar file bij calling the Hello class main function
user$ java -cp httpjartest.jar nl.sysgarden.Hello
Hello.function.main
3) Putting up the http deamon. Go to the directory where the jarfile is and activate the python webserver.
python -m SimpleHTTPServer 8080
Now we can download the jar file bij it's url http://localhost:8080/httpjartest.jar Next and final is creating the Jython app that starts and dynamicly adds the httpjartest.jar file to the systemclassloader.
$ cat classloaderExample.py 
import java.lang.System
import java.net.URLClassLoader
import java.net.URL

def printObject(obj):
 print 'obj:' + str(obj) 
 print 'cls:' + str(obj.getClass().getName())
 
def addJarToClassLoader(u):
        sysloader = java.lang.ClassLoader.getSystemClassLoader()
        sysclass = sysloader.getClass()
        #print str(sysclass.getDeclaredMethods())
        method = sysclass.getDeclaredMethod("addAppURL", [java.net.URL])
        print 'method= ' + str(method)
        method.setAccessible(1)
        jar_a = java.net.URL(u)
        b = method.invoke(sysloader, [jar_a])
        return sysloader

print 'step 1 download jar file and add it to the systemclass loader' 
sysloader = addJarToClassLoader('http://localhost:8080/httpjartest.jar' )
import nl.sysgarden.Hello
print 'step 2 create Hello object and print output' 
a=nl.sysgarden.Hello()
a.p1()
printObject(a)
Running the classloaderExample.py file
bash-3.2$ java -jar jython-standalone-2.5.3.jar classloaderExample.py 
step 1 download jar file and add it to the systemclass loader
method= void sun.misc.Launcher$AppClassLoader.addAppURL(java.net.URL)
step 2 create Hello object and print output
Hello.function.Constuctor
Hello.funtion.p1
obj:nl.sysgarden.Hello@6da05bdb
cls:nl.sysgarden.Hello

Geen opmerkingen:

Een reactie posten