Search in sources :

Example 1 with CeylonModuleClassLoader

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());
    }
}
Also used : ModuleLoadException(org.eclipse.ceylon.model.runtime.CeylonModuleClassLoader.ModuleLoadException) CeylonModuleClassLoader(org.eclipse.ceylon.model.runtime.CeylonModuleClassLoader) ModuleImport(org.eclipse.ceylon.model.typechecker.model.ModuleImport) CeylonModuleClassLoader(org.eclipse.ceylon.model.runtime.CeylonModuleClassLoader) Metamodel(org.eclipse.ceylon.compiler.java.runtime.metamodel.Metamodel) HashSet(java.util.HashSet)

Example 2 with CeylonModuleClassLoader

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);
    }
}
Also used : ModelResolutionException(org.eclipse.ceylon.model.loader.ModelResolutionException) CeylonModuleClassLoader(org.eclipse.ceylon.model.runtime.CeylonModuleClassLoader) CeylonModuleClassLoader(org.eclipse.ceylon.model.runtime.CeylonModuleClassLoader) LazyModule(org.eclipse.ceylon.model.loader.model.LazyModule) Module(org.eclipse.ceylon.model.typechecker.model.Module)

Aggregations

CeylonModuleClassLoader (org.eclipse.ceylon.model.runtime.CeylonModuleClassLoader)2 HashSet (java.util.HashSet)1 Metamodel (org.eclipse.ceylon.compiler.java.runtime.metamodel.Metamodel)1 ModelResolutionException (org.eclipse.ceylon.model.loader.ModelResolutionException)1 LazyModule (org.eclipse.ceylon.model.loader.model.LazyModule)1 ModuleLoadException (org.eclipse.ceylon.model.runtime.CeylonModuleClassLoader.ModuleLoadException)1 Module (org.eclipse.ceylon.model.typechecker.model.Module)1 ModuleImport (org.eclipse.ceylon.model.typechecker.model.ModuleImport)1