/* * @implementation * If you modify this method, you should also modify the related method * StandaloneJarBuilder.getStartPointInstanceJavaExpression */ RTValue getStartPointInstance( String className, MachineFunction mf, RTExecutionContext executionContext) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, NoSuchFieldException { if (mf == null) { throw new NullPointerException( "Invalid MachineFunction in CALClassLoader.getStartPointInstance() for " + className + "."); } Class<?> c = loadClass(className); if (mf.isDataConstructor()) { // This is a data constructor. // Get the static 'make' method. Method m = c.getMethod("make", new Class[] {}); return (RTValue) m.invoke(null, new Object[] {}); } FunctionGroupInfo fgi = module.getFunctionGroupInfo(mf); if (fgi == null) { throw new NullPointerException( "Invalid FunctionGroupInfo in CALClassLoader.getStartPointInstance() for " + mf.getQualifiedName() + "."); } if (mf.getArity() == 0) { // Get the static 'make' method. if (fgi.getNCAFs() + fgi.getNZeroArityFunctions() <= 1) { Method m = c.getMethod("make", new Class[] {RTExecutionContext.class}); return (RTValue) m.invoke(null, new Object[] {executionContext}); } else { Method m = c.getMethod("make", new Class[] {int.class, RTExecutionContext.class}); int functionIndex = fgi.getFunctionIndex(mf.getName()); return (RTValue) m.invoke(null, new Object[] {Integer.valueOf(functionIndex), executionContext}); } } // Access the static instance field. String instanceFieldName = CALToJavaNames.getInstanceFieldName(mf.getQualifiedName(), module); Field field = c.getField(instanceFieldName); return (RTValue) field.get(null); }
/** * {@inheritDoc} This classloader implementation calls findClass() on the current instance, before * calling loadClass() on the parent. */ @Override protected Class<?> findClass(String name) throws ClassNotFoundException { final long beforeFindClass; if (PERFORM_TIMING) { beforeFindClass = System.currentTimeMillis(); } else { beforeFindClass = 0; } if (DEBUG_OUTPUT) { if (adjunctLoader) { System.out.println( "adjunct loader for " + getModuleName() + ": findClass - " + name + " => thread = " + getCurrentThreadName()); } else { System.out.println( "loader for " + getModuleName() + ": findClass - " + name + " => thread = " + getCurrentThreadName()); } } // The adjunct loader should only return the class if it's in the set of adjunct classes. if (adjunctLoader && !adjunctClasses.contains(name) && (name.indexOf('$') < 0 || !adjunctClasses.contains(name.substring(0, name.indexOf('$'))))) { throw new ClassNotFoundException(); } // Get the module package component of the request class. ModuleName classModuleName = CALToJavaNames.getModuleNameFromPackageName(name); if (classModuleName == null) { throw new ClassNotFoundException(); } // Check if we handle this package. if (classModuleName.equals(getModuleName())) { byte[] data = getBytecodeForClassInternal(name); // Instantiate the class. if (data == null) { // TODOEL: perhaps this should throw a NoClassDefFoundError. // This would only make sense if we can ensure that this classloader can only be asked for // a class by our code -- // it wouldn't do for a client to encounter a LinkageError if it were to ask the // classloader for such a class. throw new ClassNotFoundException("Unable to find class: " + name); } // Increment the number of classes and bytes loaded nClassesLoaded++; nBytesLoaded += data.length; Class<?> c = defineClass(name, data, 0, data.length); // Add to the list of loaded classes. This is used when resetting cached CAF results. loadedClasses.add(c); if (PERFORM_TIMING) { long afterFindClass = System.currentTimeMillis(); findClassTimeMS += (afterFindClass - beforeFindClass); } if (DUMP_LOADED_CLASS_NAMES) { System.out.println(name); // System.out.println(name + " " + data.length); } if (DEBUG_OUTPUT) { System.out.println(" Found"); } return c; } // Classes in other modules will always be loaded by the module loader, never by the adjunct // loader, so we only need to check for the class being in another module if this loader // is not an adjunct loader. if (!adjunctLoader) { CALClassLoader moduleLoader = dependeeModuleLoaders.get(classModuleName); if (moduleLoader != null) { return moduleLoader.loadClass(name); } } throw new ClassNotFoundException( "Unable to find class: " + name + " with CALClassLoader for module " + getModuleName()); }