package org.simantics.scl.compiler.runtime;
-import gnu.trove.map.hash.THashMap;
-
import java.util.Map;
import org.simantics.scl.compiler.constants.Constant;
+import gnu.trove.map.hash.THashMap;
+
public class ExpressionClassLoader extends ClassLoader implements MutableClassLoader {
public static final boolean VALIDATE_CLASS_NAMES = true;
public static final boolean TRACE_CLASS_CREATION = false;
String basePackageName;
- THashMap<String, byte[]> localClasses = new THashMap<String, byte[]>();
+ public THashMap<String, byte[]> localClasses = new THashMap<String, byte[]>();
THashMap<String, RuntimeModule> runtimeModuleMap;
int transientPackageId = 0;
THashMap<Constant,Object> valueCache = new THashMap<Constant,Object>();
if(bytes == null)
throw new ClassNotFoundException(name);
- return defineClass(name, bytes, 0, bytes.length);
+ clazz = defineClass(name, bytes, 0, bytes.length);
+ resolveClass(clazz);
+
+ return clazz;
+
+ }
+
+ @Override
+ public byte[] getBytes(String name) {
+ // Non-SCL classes are not handled here
+ if(!name.startsWith(SCL_PACKAGE_PREFIX))
+ return null;
+
+ // Determine the id of the class loader which is responsible of the class
+ String requestedModuleName = RuntimeModule.extractClassLoaderId(name);
+
+ // Is class defined locally in this class loader?
+ if(requestedModuleName.equals(basePackageName)) {
+ String internalName = name.replace('.', '/');
+ byte[] bytes = localClasses.get(internalName);
+ if(bytes != null)
+ return bytes;
+ return localClasses.get(internalName);
+ }
+
+ // Find suitable class loader that has this class locally
+ {
+ RuntimeModule parentModule = runtimeModuleMap.get(requestedModuleName);
+ if(parentModule == null)
+ return null;
+
+ // Find the class from the ancestor class loader
+ return parentModule.classLoader.getBytes(name);
+ }
}
private Class<?> getClass(String name) throws ClassNotFoundException {