use of org.eclipse.ceylon.model.runtime.CeylonModuleClassLoader in project ceylon by eclipse.
the class Metamodel method loadModule.
private static void loadModule(String namespace, org.eclipse.ceylon.model.typechecker.model.Module declaration, Set<org.eclipse.ceylon.model.typechecker.model.Module> visitedModules, boolean optional) {
// don't do if not running JBoss modules
if (!isJBossModules()) {
return;
}
// no loading required for these
if (JDKUtils.isJDKModule(declaration.getNameAsString()) || JDKUtils.isOracleJDKModule(declaration.getNameAsString()))
return;
try {
// Stef: this can fail, in particular is the TCCCL is that of a bootstrap module CL since we can't override those
// if it does we have to resort to reflection to get around this
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
if (contextClassLoader instanceof CeylonModuleClassLoader) {
// this will return null for bootstrap modules
String modname = ModuleUtil.makeModuleName(namespace, declaration.getNameAsString(), null);
CeylonModuleClassLoader newModuleClassLoader = ((CeylonModuleClassLoader) contextClassLoader).loadModule(modname, declaration.getVersion());
// if we can force it loaded, let's do
if (newModuleClassLoader != null) {
// this can complete in another thread or this thread
newModuleClassLoader.registerInMetaModel();
}
if (!declaration.isAvailable()) {
// perhaps it is being loaded in another thread, wait for it
Object lock = getLock();
synchronized (lock) {
int tries = RuntimeModelLoader.MAX_JBOSS_MODULES_WAITS;
while (!declaration.isAvailable()) {
try {
lock.wait(RuntimeModelLoader.JBOSS_MODULES_TIMEOUT);
} catch (InterruptedException e) {
throw Metamodel.newModelError("Interrupted");
}
if (tries-- < 0)
throw Metamodel.newModelError("JBoss modules failed to make module available: " + declaration.getNameAsString() + "/" + declaration.getVersion());
}
}
}
}
if (visitedModules == null)
visitedModules = new HashSet<org.eclipse.ceylon.model.typechecker.model.Module>();
// do not visit this module again
visitedModules.add(declaration);
// make sure its imports are also loaded
for (ModuleImport mi : declaration.getImports()) {
org.eclipse.ceylon.model.typechecker.model.Module importedModule = mi.getModule();
// don't try loading optional modules
if (mi.isOptional())
continue;
// make sure we don't run in circles
if (importedModule != null && !visitedModules.contains(importedModule)) {
String ns = mi.getNamespace() != null ? mi.getNamespace() : namespace;
getOrCreateMetamodel(ns, importedModule, visitedModules, mi.isOptional());
}
}
} catch (ModuleLoadException e) {
// present. Also not an issue for optional modules.
if (!declaration.isDefaultModule() && !optional)
throw Metamodel.newModelError(e.toString());
} catch (SecurityException e) {
throw Metamodel.newModelError(e.toString());
} catch (IllegalArgumentException e) {
throw Metamodel.newModelError(e.toString());
}
}
use of org.eclipse.ceylon.model.runtime.CeylonModuleClassLoader in project ceylon by eclipse.
the class RuntimeModelLoader method findModuleForClass.
public Module findModuleForClass(Class<?> klass) {
ClassLoader cl = klass.getClassLoader();
if (cl instanceof CeylonModuleClassLoader) {
CeylonModuleClassLoader classLoader = (CeylonModuleClassLoader) cl;
String name = classLoader.getModuleName();
String version = classLoader.getModuleVersion();
String cacheKey = cacheKeyByModule(name, version);
Module ret = moduleCache.get(cacheKey);
if (ret == null) {
// there's a good chance we didn't get the module loaded in time, wait until that classloader is
// registered then, but give it a nudge:
// this can complete in another thread or this thread
classLoader.registerInMetaModel();
Object lock = getLock();
synchronized (lock) {
int tries = MAX_JBOSS_MODULES_WAITS;
while (!classLoaders.containsValue(cl)) {
try {
lock.wait(JBOSS_MODULES_TIMEOUT);
} catch (InterruptedException e) {
throw new ModelResolutionException(e);
}
if (tries-- < 0)
throw new ModelResolutionException("Failed to find registered classloader for " + klass);
}
ret = moduleCache.get(cacheKey);
}
}
return ret;
} 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);
// even on jboss modules, the jdk has no class loader, so jdk classes will have to be resolved
// to the jdk modules by package
String jdkModuleName = JDKUtils.getJDKModuleNameForPackage(pkgName);
if (jdkModuleName != null)
return findModule(jdkModuleName, JDKUtils.jdk.version);
if (isDynamicMetamodel())
return lazyLoadModuleForPackage(pkgName);
return lookupModuleByPackageName(pkgName);
}
}
Aggregations