Monday, November 10, 2008

How to Invoke Jar File using Dynamic Path

This post describe how to invoke some jar file using dynamic path.

First Create ZipClassLoader
package Lib;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.NoSuchElementException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

public  class ZipClassLoader extends ClassLoader {
    private  ZipFile file;



    public ZipClassLoader(String filename) throws IOException {
        this.file = new ZipFile(filename);
    }
    public ZipClassLoader(File File_Zip) throws IOException {
        this.file = new ZipFile(File_Zip);
    }
    public ZipEntry[] getListEntry(){
        Enumeration eZe = file.entries();
        ArrayList lstZe=new ArrayList();
        while (eZe.hasMoreElements()) {
            lstZe.add(eZe.nextElement());
        }
        ZipEntry[] arrZe=new ZipEntry[lstZe.size()];
        lstZe.toArray(arrZe);
        return arrZe;
    }
    @Override
    protected Class findClass(String name) throws ClassNotFoundException {
        ZipEntry entry = this.file.getEntry(name.replace('.', '/') + ".class");
        if (entry == null) {
            throw new ClassNotFoundException(name);
        }
        try {
            byte[] array = new byte[1024];
            InputStream in = this.file.getInputStream(entry);

            ByteArrayOutputStream out = new ByteArrayOutputStream(array.length);
            int length = in.read(array);
            while (length > 0) {
                out.write(array, 0, length);
                length = in.read(array);
            }
            return defineClass(name, out.toByteArray(), 0, out.size());
        }
        catch (IOException exception) {
            throw new ClassNotFoundException(name, exception);
        }
    }
    protected Class findClass(ZipEntry zipEntry) throws IOException {
        ZipEntry entry = zipEntry;
        byte[] array = new byte[1024];
//        ZipFile.
        InputStream in = this.file.getInputStream(entry);
        ByteArrayOutputStream out = new ByteArrayOutputStream(array.length);
        int length = in.read(array);
        while (length > 0) {
            out.write(array, 0, length);
            length = in.read(array);
        }
//        defi
        return defineClass(zipEntry.getName(), out.toByteArray(), 0, out.size());
    }
    
    
    @Override
    protected URL findResource(String name) {
        ZipEntry entry = this.file.getEntry(name);
        if (entry == null) {
            return null;
        }
        try {
            return new URL("jar:file:" + this.file.getName() + "!/" + entry.getName());
        }
        catch (MalformedURLException exception) {
            return null;
        }
    }

    @Override
    protected Enumeration findResources(final String name) {
        return new Enumeration() {
            private URL element = findResource(name);

            public boolean hasMoreElements() {
                return this.element != null;
            }

            public URL nextElement() {
                if (this.element != null) {
                    URL element = this.element;
                    this.element = null;
                    return element;
                }
                throw new NoSuchElementException();
            }
        };
    }
    
}

U can use ZipClassLoader by main class


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package jarinvoker;

import Lib.ZipClassLoader;
import java.io.File;
import java.io.IOException;
import java.util.zip.ZipEntry;

/**
 *
 * @author Ratno Kustiawan
 */
public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
        // TODO code application logic here
        File f=new File("H:/Prepare For Modular System/JarToInvoke/dist/JarToInvoke.jar");
        ZipClassLoader z=new ZipClassLoader(f);
        System.out.println("-------------------------------------");
        System.out.println("List Entry");
        System.out.println("-------------------------------------");
        ZipEntry[] lstEntry=z.getListEntry();
        for (ZipEntry zipEntry : lstEntry) {
            System.out.println(zipEntry.getName());
        }
        System.out.println("-------------------------------------");
        System.out.println("Invoke Method");
        System.out.println("-------------------------------------");
        Class c=z.loadClass("proces.Target");
        c.newInstance();
    }

}


No comments: