diff --git a/runtime/com/redhat/ceylon/compiler/java/runtime/model/RuntimeModelLoader.java b/runtime/com/redhat/ceylon/compiler/java/runtime/model/RuntimeModelLoader.java index 4ffefff5d..5e100471c 100644 --- a/runtime/com/redhat/ceylon/compiler/java/runtime/model/RuntimeModelLoader.java +++ b/runtime/com/redhat/ceylon/compiler/java/runtime/model/RuntimeModelLoader.java @@ -5,10 +5,15 @@ import java.util.List; import java.util.Map; +import org.jboss.modules.ModuleClassLoader; + import com.redhat.ceylon.cmr.api.ArtifactResult; import com.redhat.ceylon.cmr.impl.JULLogger; import com.redhat.ceylon.compiler.loader.impl.reflect.CachedTOCJars; import com.redhat.ceylon.compiler.loader.impl.reflect.ReflectionModelLoader; +import com.redhat.ceylon.compiler.loader.impl.reflect.mirror.ReflectionClass; +import com.redhat.ceylon.compiler.loader.impl.reflect.mirror.ReflectionUtils; +import com.redhat.ceylon.compiler.loader.mirror.ClassMirror; import com.redhat.ceylon.compiler.loader.model.LazyModule; import com.redhat.ceylon.compiler.typechecker.analyzer.ModuleManager; import com.redhat.ceylon.compiler.typechecker.model.Module; @@ -17,6 +22,7 @@ public class RuntimeModelLoader extends ReflectionModelLoader { private Map classLoaders = new HashMap(); + private Map moduleCache = new HashMap(); private CachedTOCJars jars = new CachedTOCJars(); public RuntimeModelLoader(ModuleManager moduleManager, Modules modules) { @@ -24,35 +30,31 @@ public RuntimeModelLoader(ModuleManager moduleManager, Modules modules) { } @Override - protected List getPackageList(String packageName) { + protected List getPackageList(Module module, String packageName) { return jars.getPackageList(packageName); } @Override - protected boolean packageExists(String packageName) { + protected boolean packageExists(Module module, String packageName) { return jars.packageExists(packageName); } @Override - protected Class loadClass(String name) { - for(ClassLoader cl : classLoaders.values()){ - try{ - return cl.loadClass(name); - }catch(ClassNotFoundException x){ - // keep trying - } + protected Class loadClass(Module module, String name) { + ClassLoader classLoader = classLoaders.get(module); + if(classLoader == null) + return null; + try{ + return classLoader.loadClass(name); + }catch(ClassNotFoundException x){ + return null; } - return null; -// // try the system class loader -// try { -// return ClassLoader.getSystemClassLoader().loadClass(name); -// } catch (ClassNotFoundException e) { -// return null; -// } } @Override public void addModuleToClassPath(Module module, ArtifactResult artifact) { + String cacheKey = cacheKeyByModule(module.getNameAsString(), module.getVersion()); + moduleCache.put(cacheKey, module); if(artifact == null) return; File file = artifact.artifact(); @@ -66,4 +68,33 @@ public void addModuleClassLoader(Module module, ClassLoader classLoader) { classLoaders.put(module, classLoader); } + @Override + protected Module findModuleForClassMirror(ClassMirror classMirror) { + Class klass = ((ReflectionClass)classMirror).klass; + return findModuleForClass(klass); + } + + public Module findModuleForClass(Class klass){ + ClassLoader cl = klass.getClassLoader(); + if(cl instanceof ModuleClassLoader){ + ModuleClassLoader classLoader = (ModuleClassLoader)cl; + org.jboss.modules.Module jbossModule = classLoader.getModule(); + String name = jbossModule.getIdentifier().getName(); + String version = jbossModule.getIdentifier().getSlot(); + String cacheKey = cacheKeyByModule(name, version); + return moduleCache.get(cacheKey); + }else{ + // revert to a single classloader version? + // FIXME: perhaps we can have other one-classloader-to-one-module setups than jboss modules? + String pkgName = ReflectionUtils.getPackageName(klass); + return lookupModuleInternal(pkgName); + } + } + + private String cacheKeyByModule(String name, String version) { + if(name.equals(Module.DEFAULT_MODULE_NAME)) + return name + "/"; // no version + return name + "/" + version; + } + } diff --git a/runtime/com/redhat/ceylon/compiler/java/runtime/model/RuntimeModuleManager.java b/runtime/com/redhat/ceylon/compiler/java/runtime/model/RuntimeModuleManager.java index 1ee0fe93e..018146d64 100644 --- a/runtime/com/redhat/ceylon/compiler/java/runtime/model/RuntimeModuleManager.java +++ b/runtime/com/redhat/ceylon/compiler/java/runtime/model/RuntimeModuleManager.java @@ -61,10 +61,10 @@ public void loadModule(String name, String version, ArtifactResult artifact, Cla modelLoader.addModuleToClassPath(module, artifact); modelLoader.addModuleClassLoader(module, classLoader); module.setAvailable(true); + if(!module.isDefault()){ - Module compiledModule = modelLoader.loadCompiledModule(name); // FIXME: dependencies of Ceylon modules? - if(compiledModule == null){ + if(!modelLoader.loadCompiledModule(module)){ // we didn't find module.class so it must be a java module if it's not the default module ((LazyModule)module).setJava(true); @@ -86,4 +86,8 @@ public void loadModule(String name, String version, ArtifactResult artifact, Cla public RuntimeModelLoader getModelLoader() { return (RuntimeModelLoader) super.getModelLoader(); } + + public Module findModuleForClass(java.lang.Class klass){ + return getModelLoader().findModuleForClass(klass); + } } diff --git a/runtime/com/redhat/ceylon/compiler/java/runtime/model/TypeDescriptor.java b/runtime/com/redhat/ceylon/compiler/java/runtime/model/TypeDescriptor.java index 468d39719..a4f9309be 100644 --- a/runtime/com/redhat/ceylon/compiler/java/runtime/model/TypeDescriptor.java +++ b/runtime/com/redhat/ceylon/compiler/java/runtime/model/TypeDescriptor.java @@ -5,6 +5,7 @@ import com.redhat.ceylon.compiler.loader.ModelLoader.DeclarationType; import com.redhat.ceylon.compiler.typechecker.model.IntersectionType; +import com.redhat.ceylon.compiler.typechecker.model.Module; import com.redhat.ceylon.compiler.typechecker.model.NothingType; import com.redhat.ceylon.compiler.typechecker.model.ProducedType; import com.redhat.ceylon.compiler.typechecker.model.TypeDeclaration; @@ -79,7 +80,8 @@ public ProducedType toProducedType(RuntimeModuleManager moduleManager){ public ProducedType toProducedType(ProducedType qualifyingType, RuntimeModuleManager moduleManager){ String typeName = klass.getName(); - TypeDeclaration decl = (TypeDeclaration) moduleManager.getModelLoader().getDeclaration(typeName, DeclarationType.TYPE); + Module module = moduleManager.findModuleForClass(klass); + TypeDeclaration decl = (TypeDeclaration) moduleManager.getModelLoader().getDeclaration(module, typeName, DeclarationType.TYPE); List typeArgs = new ArrayList(typeArguments.length); for(TypeDescriptor typeArg : typeArguments){ typeArgs.add(typeArg.toProducedType(moduleManager));