00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 package org.objectweb.proactive.core.mop;
00032
00033 import java.lang.reflect.InvocationTargetException;
00034 import java.lang.reflect.Method;
00035 import java.net.URL;
00036 import java.net.URLClassLoader;
00037 import java.util.Hashtable;
00038
00039 import org.apache.log4j.Logger;
00040 import org.objectweb.proactive.core.util.log.Loggers;
00041 import org.objectweb.proactive.core.util.log.ProActiveLogger;
00042
00043
00044 public class MOPClassLoader extends URLClassLoader {
00045 static Logger logger = ProActiveLogger.getLogger(Loggers.MOP);
00046
00047
00048
00049 public static String BYTE_CODE_MANIPULATOR = (System.getProperty(
00050 "byteCodeManipulator") != null)
00051 ? System.getProperty("byteCodeManipulator") : "javassist";
00052 protected static Hashtable<String, byte[]> classDataCache = new Hashtable<String, byte[]>();
00053 protected static MOPClassLoader mopCl = null;
00054
00059 public static synchronized MOPClassLoader getMOPClassLoader() {
00060 if (MOPClassLoader.mopCl == null) {
00061 MOPClassLoader.mopCl = MOPClassLoader.createMOPClassLoader();
00062 }
00063 return MOPClassLoader.mopCl;
00064 }
00065
00066 public MOPClassLoader() {
00067 super(new URL[] { });
00068 }
00069
00077 public byte[] getClassData(String classname) {
00078 byte[] cb = null;
00079 cb = classDataCache.get(classname);
00080 if (cb == null) {
00081 if (logger.isDebugEnabled()) {
00082 logger.debug(
00083 "MOPClassLoader: class " + classname + " not found, trying to generate it");
00084 }
00085 try {
00086 this.loadClass(classname);
00087 } catch (ClassNotFoundException e) {
00088 e.printStackTrace();
00089 }
00090 cb = classDataCache.get(classname);
00091 }
00092 return cb;
00093 }
00094
00095 private MOPClassLoader(ClassLoader parent, URL[] urls) {
00096 super(urls, parent);
00097 }
00098
00099 public void launchMain(String[] args) throws Throwable {
00100 try {
00101
00102 Class cl = Class.forName(args[0], true, this);
00103
00104
00105 Class[] argTypes = { args.getClass() };
00106 Method mainMethod = cl.getMethod("main", argTypes);
00107
00108
00109 String[] newArgs = new String[args.length - 1];
00110 System.arraycopy(args, 1, newArgs, 0, args.length - 1);
00111
00112 Object[] mainArgs = { newArgs };
00113 mainMethod.invoke(null, mainArgs);
00114 } catch (ClassNotFoundException e) {
00115 logger.error("Launcher: cannot find class " + args[0]);
00116 } catch (NoSuchMethodException e) {
00117 logger.error("Launcher: class " + args[0] +
00118 " does not contain have method void 'public void main (String[])'");
00119 } catch (InvocationTargetException e) {
00120 throw e.getTargetException();
00121 }
00122 return;
00123 }
00124
00125 protected static MOPClassLoader createMOPClassLoader() {
00126
00127 ClassLoader currentClassLoader = null;
00128
00129 try {
00130 Class c = Class.forName(
00131 "org.objectweb.proactive.core.mop.MOPClassLoader");
00132 currentClassLoader = c.getClassLoader();
00133 } catch (ClassNotFoundException e) {
00134 e.printStackTrace();
00135 }
00136 URL[] urls = null;
00137
00138
00139
00140 if (currentClassLoader instanceof java.net.URLClassLoader) {
00141
00142 urls = ((URLClassLoader) currentClassLoader).getURLs();
00143 } else {
00144 urls = new URL[0];
00145 }
00146
00147
00148 return new MOPClassLoader(currentClassLoader, urls);
00149 }
00150
00151 protected Class<?> findClass(String name) throws ClassNotFoundException {
00152 return super.findClass(name);
00153 }
00154
00155 public Class<?> loadClass(String name) throws ClassNotFoundException {
00156 return this.loadClass(name, null, null, false);
00157 }
00158
00159
00160 public Class loadClass(String name, Class[] genericParameters) throws ClassNotFoundException {
00161 return this.loadClass(name, genericParameters, null, false);
00162 }
00163
00164 public Class loadClass(String name, Class[] genericParameters, ClassLoader cl)
00165 throws ClassNotFoundException {
00166 return this.loadClass(name, genericParameters, cl, false);
00167 }
00168
00169 protected synchronized Class loadClass(String name, Class[] genericParameters, ClassLoader cl,
00170 boolean resolve) throws ClassNotFoundException {
00171 if (this.getParent() != null) {
00172 try {
00173 return this.getParent().loadClass(name);
00174 } catch (ClassNotFoundException e) {
00175
00176 }
00177 } else {
00178
00179
00180
00181 try {
00182 return Thread.currentThread().getContextClassLoader().loadClass(name);
00183 } catch (ClassNotFoundException e) {
00184
00185 }
00186 }
00187 try {
00188 if (cl != null) {
00189 return cl.loadClass(name);
00190 } else {
00191 return Class.forName(name);
00192 }
00193 } catch (ClassNotFoundException e) {
00194
00195
00196 if (Utils.isStubClassName(name)) {
00197 logger.info("Generating class : " + name);
00198
00199 String classname = Utils.convertStubClassNameToClassName(name);
00200
00201 byte[] data = null;
00202
00203
00204
00205
00206
00207 if (BYTE_CODE_MANIPULATOR.equals("javassist")) {
00208 data = JavassistByteCodeStubBuilder.create(classname, genericParameters);
00209 MOPClassLoader.classDataCache.put(name, data);
00210 } else {
00211
00212 logger.error(
00213 "byteCodeManipulator argument is optionnal. If specified, it can only be set to javassist (ASM is no longer supported).");
00214 logger.error(
00215 "Any other setting will result in the use of javassist, the default bytecode manipulator framework");
00216 }
00217
00218
00219
00220
00221 try {
00222 Class clc = Class.forName("java.lang.ClassLoader");
00223 Class[] argumentTypes = new Class[5];
00224 argumentTypes[0] = name.getClass();
00225 argumentTypes[1] = data.getClass();
00226 argumentTypes[2] = Integer.TYPE;
00227 argumentTypes[3] = Integer.TYPE;
00228 argumentTypes[4] = Class.forName(
00229 "java.security.ProtectionDomain");
00230
00231 Method m = clc.getDeclaredMethod("defineClass",
00232 argumentTypes);
00233 m.setAccessible(true);
00234
00235 Object[] effectiveArguments = new Object[5];
00236 effectiveArguments[0] = name;
00237 effectiveArguments[1] = data;
00238 effectiveArguments[2] = new Integer(0);
00239 effectiveArguments[3] = new Integer(data.length);
00240 effectiveArguments[4] = this.getClass().getProtectionDomain();
00241
00242
00243
00244 if (this.getParent() == null) {
00245 return (Class) m.invoke(Thread.currentThread()
00246 .getContextClassLoader(),
00247 effectiveArguments);
00248 } else {
00249 return (Class) m.invoke(this.getParent(),
00250 effectiveArguments);
00251 }
00252 } catch (Exception ex) {
00253 ex.printStackTrace();
00254 throw new ClassNotFoundException(ex.getMessage());
00255 }
00256 } else {
00257 logger.debug("Cannot generate class " + name + " as a stub class");
00258 throw e;
00259 }
00260 }
00261 }
00262 }