/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- * $Id: ImageLoader.java 491 2007-10-12 17:25:56Z metlov $ * * This file is part of the Java Expressions Library (JEL). * For more information about JEL visit : * http://kinetic.ac.donetsk.ua/JEL/ * * (c) 1998 -- 2007 by Konstantin Metlov(metlov@kinetic.ac.donetsk.ua); * * JEL is Distributed under the terms of GNU General Public License. * This code comes with ABSOLUTELY NO WARRANTY. * For license details see COPYING file in this directory. */ package gnu.jel; import gnu.jel.debug.Debug; /** * Loads JEL-generated classes into Java VM. * <P> Specifics of JEL generated classes is that the class name UTF8 is always * the first entry in the constant pool. This loader will not load * other classes. */ public class ImageLoader extends ClassLoader { String name; byte[] bytes; Class c; ClassLoader parent; private ImageLoader(String name, byte[] bytes) { this.name=name; this.bytes=bytes; this.c=null; this.parent=this.getClass().getClassLoader(); }; /** * Loads given JEL-generated image under its own name. * @param image to load * @return the class object for the new class or <TT>null</TT> * if unsuccessful. */ public static Class load(byte[] image) { if (Debug.enabled) Debug.check(image[10]==1, "Attempt to load non-JEL generated class file"); // JEL generated class file never have UNICODE class name // although they might reference UNICODE methods, etc... int len=(image[11]<<8)+image[12]; char[] nameChr=new char[len]; for(int i=0;i<len;i++) nameChr[i]=(char)image[13+i]; String name=String.copyValueOf(nameChr); try { // load class ImageLoader il=new ImageLoader(name,image); return il.loadClass(name); } catch(Exception e) { if (Debug.enabled) Debug.reportThrowable(e); }; return null; }; // // Please uncomment the code below and use it for loading expressions // // (e.g. by commenting the "load" method above and renaming // // "loadRenamed"->"load" below) if You have an older version // // of JDK (below 1.1.7, AFAIK), which does not allow classes with // // the _same_ names to be loaded by _different_ classloaders. // // // // Number of loaded expressions in this session // private transient volatile static long expressionUID=0; // /** // * Prefix of the expression classname // * <P>Example: "gnu.jel.generated.E_" // */ // public static String classNamePrefix="gnu.jel.generated.E_"; // /** // * Loads given JEL-generated image under unique name. // * <P>The unique name is generated by appending a steadily incremented // * number to the <TT>classNamePrefix</TT>. // * @param image to load // * @return the class object for the new class or <TT>null</TT> // * if unsuccessful. // * @see gnu.jel.ImageLoader#classNamePrefix // */ // public static Class loadRenamed(byte[] image) { // if (Debug.enabled) // Debug.check(image[10]==1, // "Attempt to load non-JEL generated class file"); // String newname=classNamePrefix+Long.toString(expressionUID++); // String newnameHF=TypesStack.toHistoricalForm(newname); // // JEL generated class file never have UNICODE class name // // although they might reference UNICODE methods, etc... // int len=(image[11]<<8)+image[12]; // int newlen=newname.length(); // byte[] newimage=new byte[image.length-len+newlen]; // System.arraycopy(image,0,newimage,0,11); // newimage[11]=(byte)(newlen>>8); // newimage[12]=(byte)newlen; // for(int i=0;i<newlen;i++) // newimage[13+i]=(byte)newnameHF.charAt(i); // System.arraycopy(image,13+len,newimage,13+newlen,image.length-13-len); // try { // // load class // ImageLoader il=new ImageLoader(newname,newimage); // return il.loadClass(newname); // } catch(Exception e) { // if (Debug.enabled) // Debug.reportThrowable(e); // }; // return null; // }; protected synchronized Class loadClass(String name, boolean resolve) throws java.lang.ClassNotFoundException { if (!name.equals(this.name)) { if (parent!=null) return parent.loadClass(name); else return findSystemClass(name); } else { if(c==null) { c = defineClass(name,bytes, 0, bytes.length,this.getClass().getProtectionDomain()); if (resolve) resolveClass(c); } return c; } }; };