alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.axis2.tools.idea;

import java.io.*;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

/**
 * Author : Deepal Jayasinghe
 * Date: Jul 22, 2005
 * Time: 2:25:59 PM
 */
public class PluginClassLoader extends URLClassLoader {

    //urls which gives to create the classLoader
    private URL[] urls;

    //To keep jar files inside /lib directory in the main jar
    private ArrayList lib_jars_list;


    /**
     * PluginClassLoader is exetend form URLClassLoader , and the constructor
     * has not overide the super constroctor , but has done some stuff to find out
     * jar fils inside /lib director
     *
     * @param urls   <code>URL
     * @param parent parent classloader <code>ClassLoader
     */
    public PluginClassLoader(URL[] urls, ClassLoader parent) {
        super(urls, parent);
        this.urls = urls;
        lib_jars_list = new ArrayList();
        findLibJars();
    }

    /**
     * This just search for jar files inside /lib dirctory and if there are any then those
     * will be added to the arraylit (only the name of the jar file)
     */
    private void findLibJars() {
        /**
         * though the URL array can contains one or more urls , I have only consider the
         * first one , that is this classLoader is only for Axis2 stuff and the classloader
         * is created by Deployment , so there wont be any chance to have more the one urls for
         * the URL array list
         */
        File file = new File(urls[0].getFile());
        try {
            ZipInputStream zin = new ZipInputStream(new FileInputStream(file));
            ZipEntry entry;
            String entryName = "";
            while ((entry = zin.getNextEntry()) != null) {
                entryName = entry.getName();
                /**
                 * id the entry name start with /lib and end with .jar
                 * then those entry name will be added to the arraylist
                 */
                if (entryName != null && (entryName.startsWith("lib/") ||
                        entryName.startsWith("Lib/")) &&
                        entryName.endsWith(".jar")) {
                    lib_jars_list.add(entryName);
                }
            }
            zin.close();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * @param name <code>String  Name of the file to be loaded
     * @return <code>Class return a class object if it found else
     *         will return null or a ClassNotFoundException
     *         <p/>
     *         This method has been overridden in the following way
     *         1. It calls the super class and checks to see whether the class is there
     *         If the class is found then return it, else if super return ClassNotfoundException
     *         2. Check whether the entry corresponding to the class name exists in one of jar files
     *         in /lib director
     *         3. If it is there get the byte array out of that and create a Class object out of that
     *         by calling "defineClass()" , if it succeeds then return that else
     *         4. Throw a ClassNotFoundException
     * @throws ClassNotFoundException
     */
    protected Class findClass(final String name)
            throws ClassNotFoundException {
        Class cla = null;
        try {
            boolean foundClass = false;
            try {
                cla = super.findClass(name);
                foundClass = true;
                return cla;
            } catch (ClassNotFoundException e) {
                foundClass = false;
            }
            if (!foundClass) {
                byte raw[] = getBytes(name);
                cla = defineClass(name, raw, 0, raw.length);
                foundClass = true;
                return cla;
            }
            if (!foundClass) {
                throw new ClassNotFoundException("Class Not found : " + name);
            }

        } catch (Exception e) {

        }
        return null;
    }

    /**
     * Read jar file (/lib) one by one , then for each file craete <code>ZipInputStream
     * that and check to see wether there is any entry eith given name if it found then
     * Creat ByteArrayOutPutStream and get the class bytes to that .
     * after goning throgh each and evry jar file if there is no entry with given name
     * will throug a ClassNotFound execption
     *
     * @param filename <code>String  Name of the file to be loaded (Class Name)
     * @return bytt[]
     * @throws java.io.IOException <code>Exception
     */
    private byte[] getBytes(String filename) throws Exception {
        String completeFileName = filename;
        /**
         * Replacing org.apache. -> org/apache/...
         */
        completeFileName = completeFileName.replace('.', '/').concat(".class");
        byte raw[] = null;
        for (int i = 0; i < lib_jars_list.size(); i++) {
            String libjar_name = (String) lib_jars_list.get(i);
            InputStream in = this.getResourceAsStream(libjar_name);
            try {
                ZipInputStream zin = new ZipInputStream(in);
                ZipEntry entry;
                String entryName = "";
                while ((entry = zin.getNextEntry()) != null) {
                    entryName = entry.getName();
                    if (entryName != null &&
                            entryName.endsWith(completeFileName)) {
                        byte data[] = new byte[2048];
                        ByteArrayOutputStream out = new ByteArrayOutputStream();
                        int count;
                        while ((count = zin.read(data, 0, 2048)) != -1) {
                            out.write(data, 0, count);
                        }
                        raw = out.toByteArray();
                        out.close();
                        zin.close();
                        return raw;
                    }
                }
            } catch (IOException e) {
                throw e;
            }

        }
        throw new ClassNotFoundException("Class Not found : " + filename);
    }
}

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.