Search in sources :

Example 1 with ClassLoaderFactory

use of com.shulie.instrument.simulator.core.classloader.ClassLoaderFactory in project LinkAgent by shulieTech.

the class DefaultClassLoaderService method findExportClassLoaderFactory.

@Override
public ClassLoaderFactory findExportClassLoaderFactory(String className) {
    if (isDisposed) {
        return null;
    }
    ClassLoaderFactory exportClassLoaderFactory = exportExactlyClassesClassLoaderMap.get(className);
    String packageName = ClassUtils.getPackageName(className);
    if (exportClassLoaderFactory == null) {
        exportClassLoaderFactory = exportExactlyPackagesClassLoaderMap.get(packageName);
    }
    while (!ClassUtils.DEFAULT_PACKAGE.equals(packageName) && StringUtils.isNotBlank(packageName) && exportClassLoaderFactory == null) {
        exportClassLoaderFactory = exportPrefixPackagesClassLoaderMap.get(packageName);
        packageName = ClassUtils.getPackageName(packageName);
    }
    if (exportClassLoaderFactory == null) {
        while (!ClassUtils.DEFAULT_PACKAGE.equals(packageName) && StringUtils.isNotBlank(packageName) && exportClassLoaderFactory == null) {
            exportClassLoaderFactory = exportSuffixPackagesClassLoaderMap.get(packageName);
            packageName = ClassUtils.getNextPackageName(packageName);
        }
    }
    return exportClassLoaderFactory;
}
Also used : ClassLoaderFactory(com.shulie.instrument.simulator.core.classloader.ClassLoaderFactory)

Example 2 with ClassLoaderFactory

use of com.shulie.instrument.simulator.core.classloader.ClassLoaderFactory in project LinkAgent by shulieTech.

the class DefaultCoreModuleManager method softFlush.

/**
 * 软刷新
 * 找出有变动的模块文件,有且仅有改变这些文件所对应的模块
 */
private void softFlush() {
    if (isInfoEnabled) {
        logger.info("SIMULATOR: soft-flushing modules:{}", loadedModuleMap.keySet());
    }
    final File systemModuleLibDir = new File(config.getSystemModuleLibPath());
    try {
        final ArrayList<File> appendJarFiles = new ArrayList<File>();
        final ArrayList<CoreModule> removeCoreModules = new ArrayList<CoreModule>();
        final ArrayList<Long> checksumCRC32s = new ArrayList<Long>();
        // 1. 找出所有有变动的文件(add/remove)
        for (final File jarFile : this.moduleLoader.loadModuleLibs(config.getAppName(), config.getUserModulePaths())) {
            final long checksumCRC32;
            try {
                checksumCRC32 = FileUtils.checksumCRC32(jarFile);
            } catch (IOException cause) {
                logger.warn("SIMULATOR: soft-flushing module: compute module-jar CRC32 occur error. module-jar={};", jarFile, cause);
                continue;
            }
            checksumCRC32s.add(checksumCRC32);
            // 如果CRC32已经在已加载的模块集合中存在,则说明这个文件没有变动,忽略
            if (isChecksumCRC32Existed(checksumCRC32)) {
                if (isInfoEnabled) {
                    logger.info("SIMULATOR: soft-flushing module: module-jar is not changed, ignored. module-jar={};CRC32={};", jarFile, checksumCRC32);
                }
                continue;
            }
            if (isInfoEnabled) {
                logger.info("SIMULATOR: soft-flushing module: module-jar is changed, will be flush. module-jar={};CRC32={};", jarFile, checksumCRC32);
            }
            appendJarFiles.add(jarFile);
        }
        // 2. 找出所有待卸载的已加载用户模块
        for (final CoreModule coreModule : loadedModuleMap.values()) {
            final ClassLoaderFactory classLoaderFactory = coreModule.getClassLoaderFactory();
            // 如果是系统模块目录则跳过
            if (isOptimisticDirectoryContainsFile(systemModuleLibDir, coreModule.getJarFile())) {
                if (isDebugEnabled) {
                    logger.debug("SIMULATOR: soft-flushing module: module-jar is in system-lib, will be ignored. module-jar={};system-lib={};", coreModule.getJarFile(), systemModuleLibDir);
                }
                continue;
            }
            // 如果CRC32已经在这次待加载的集合中,则说明这个文件没有变动,忽略
            if (checksumCRC32s.contains(classLoaderFactory.getChecksumCRC32())) {
                if (isInfoEnabled) {
                    logger.info("SIMULATOR: soft-flushing module: module-jar already loaded, ignored. module-jar={};CRC32={};", coreModule.getJarFile(), classLoaderFactory.getChecksumCRC32());
                }
                continue;
            }
            if (isInfoEnabled) {
                logger.info("SIMULATOR: soft-flushing module: module-jar is changed, module will be reload/remove. module={};module-jar={};", coreModule.getModuleId(), coreModule.getJarFile());
            }
            removeCoreModules.add(coreModule);
        }
        // 3. 删除remove
        for (final CoreModule coreModule : removeCoreModules) {
            unload(coreModule, true);
        }
        // 3. 加载所有用户自定义模块
        List<ModuleSpec> userModuleSpecs = ModuleSpecUtils.loadModuleSpecs(appendJarFiles, false);
        loadModules(userModuleSpecs, "soft-flush");
    } catch (Throwable cause) {
        logger.warn("SIMULATOR: soft-flushing modules: occur error.", cause);
    }
}
Also used : ClassLoaderFactory(com.shulie.instrument.simulator.core.classloader.ClassLoaderFactory) IOException(java.io.IOException) CoreModule(com.shulie.instrument.simulator.core.CoreModule) File(java.io.File)

Example 3 with ClassLoaderFactory

use of com.shulie.instrument.simulator.core.classloader.ClassLoaderFactory in project LinkAgent by shulieTech.

the class DefaultCoreModuleManager method loadModule.

/**
 * 模块加载
 *
 * @param moduleSpec
 * @param action
 */
private void loadModule(final ModuleSpec moduleSpec, String action) {
    if (isInfoEnabled) {
        logger.info("SIMULATOR: prepare to load module {} ,file={}", moduleSpec.getModuleId(), moduleSpec.getFile().getAbsolutePath());
    }
    if (!moduleSpec.getFile().exists() || !moduleSpec.getFile().canRead()) {
        moduleSpec.setValid(false);
        logger.warn("SIMULATOR: {} modules[{}]: module-lib can not access, cause by file is not exists or can't read. module-lib={}, exists={}, canRead={}", action, moduleSpec.getModuleId(), moduleSpec.getFile(), moduleSpec.getFile().exists(), moduleSpec.getFile().canRead());
        return;
    }
    /**
     * 如果是版本不支持则也没办法正常加载 Module
     */
    if (!(VersionUtils.isLeVersion(moduleSpec.getSinceVersion(), simulatorConfig.getSimulatorVersion()) && VersionUtils.isGeVersion(moduleSpec.getUntilVersion(), simulatorConfig.getSimulatorVersion()))) {
        moduleSpec.setValid(false);
        logger.warn("SIMULATOR: {} modules[{}]: module is not enabled, cause by module version is not support simulator version, will be ignored. module-lib={}, simulator-version:{} module-support-version:{}-{}", action, moduleSpec.getModuleId(), moduleSpec.getFile(), simulatorConfig.getSimulatorVersion(), moduleSpec.getSinceVersion(), moduleSpec.getUntilVersion());
        return;
    }
    /**
     * 只有非必须的模块才可以设置禁用,不然则可以忽略
     */
    if (!moduleSpec.isMustUse()) {
        if (disabledModules.contains(moduleSpec.getModuleId())) {
            moduleSpec.setValid(false);
            logger.warn("SIMULATOR: {} modules[{}]: module is disabled, will be ignored. module-lib={}", action, moduleSpec.getModuleId(), moduleSpec.getFile());
            return;
        }
    }
    try {
        final ClassLoaderFactory moduleClassLoader = new ClassLoaderFactoryImpl(classLoaderService, config, moduleSpec.getFile(), moduleSpec.getModuleId(), moduleSpec.isMiddlewareModule());
        classLoaderService.load(moduleSpec, moduleClassLoader);
    } catch (Throwable e) {
        logger.info("load module [{}] fail, set module invalid", moduleSpec.getModuleId(), e);
        moduleSpec.setValid(false);
    }
    if (isInfoEnabled) {
        logger.info("SIMULATOR: {} modules[{}]: load module success. module-lib={}", action, moduleSpec.getModuleId(), moduleSpec.getFile());
    }
    if (CollectionUtils.isNotEmpty(moduleSpec.getDependencies())) {
        /**
         * 如果开关已经是开启状态,则直接执行即可
         */
        if (switcherManager.isAllSwitchOn(moduleSpec.getDependencies())) {
            loadModule(moduleSpec);
            if (isInfoEnabled) {
                logger.info("SIMULATOR: load module {} successful,file={}", moduleSpec.getModuleId(), moduleSpec.getFile().getAbsolutePath());
            }
        } else {
            switcherManager.registerMultiSwitchOnCallback(moduleSpec.getDependencies(), new Runnable() {

                @Override
                public void run() {
                    /**
                     * 当开启状态时执行加载
                     */
                    if (switcherManager.isAllSwitchOn(moduleSpec.getDependencies())) {
                        loadModule(moduleSpec);
                        if (isInfoEnabled) {
                            logger.info("SIMULATOR: load module {} successful,file={}", moduleSpec.getModuleId(), moduleSpec.getFile().getAbsolutePath());
                        }
                    } else {
                        /**
                         * 否则重新注册开关,因为回调执行一次就会销毁
                         */
                        switcherManager.registerMultiSwitchOnCallback(moduleSpec.getDependencies(), this);
                    }
                }
            });
        }
    } else {
        loadModule(moduleSpec);
        if (isInfoEnabled) {
            logger.info("SIMULATOR: load module {} successful,file={}", moduleSpec.getModuleId(), moduleSpec.getFile().getAbsolutePath());
        }
    }
}
Also used : ClassLoaderFactory(com.shulie.instrument.simulator.core.classloader.ClassLoaderFactory) ClassLoaderFactoryImpl(com.shulie.instrument.simulator.core.classloader.impl.ClassLoaderFactoryImpl)

Example 4 with ClassLoaderFactory

use of com.shulie.instrument.simulator.core.classloader.ClassLoaderFactory in project LinkAgent by shulieTech.

the class DefaultCoreModuleManager method unload.

/**
 * 卸载并删除注册模块
 * <p>1. 如果模块原本就不存在,则幂等此次操作</p>
 * <p>2. 如果模块存在则尝试进行卸载</p>
 * <p>3. 卸载模块之前会尝试冻结该模块</p>
 *
 * @param coreModule              等待被卸载的模块
 * @param isIgnoreModuleException 是否忽略模块异常
 * @param frozen                  卸载前是否先冻结模块
 * @throws ModuleException 卸载模块失败
 */
@Override
public CoreModule unload(CoreModule coreModule, boolean isIgnoreModuleException, boolean frozen) throws ModuleException {
    if (!coreModule.isLoaded()) {
        if (isDebugEnabled) {
            logger.debug("SIMULATOR: module already unLoaded. module={};", coreModule.getModuleId());
        }
        return coreModule;
    }
    if (isInfoEnabled) {
        logger.info("SIMULATOR: unloading module, module={};class={};", coreModule.getModuleId(), coreModule.getModule().getClass().getName());
    }
    if (frozen) {
        // 尝试冻结模块
        frozen(coreModule, isIgnoreModuleException);
    }
    // 通知生命周期
    try {
        callAndFireModuleLifeCycle(coreModule, MODULE_UNLOAD);
    } catch (ModuleException meCause) {
        if (isIgnoreModuleException) {
            logger.warn("SIMULATOR: unload module occur error, ignored. module={};class={};code={};", meCause.getModuleId(), coreModule.getModule().getClass().getName(), meCause.getErrorCode(), meCause);
        } else {
            throw meCause;
        }
    }
    String moduleId = coreModule.getModuleId();
    ClassLoaderFactory classLoaderFactory = coreModule.getClassLoaderFactory();
    // 从模块注册表中删除
    loadedModuleMap.remove(moduleId);
    // 标记模块为:已卸载
    coreModule.markLoaded(false);
    // de inject resource, free class easy
    deInjectResource(coreModule.getModule(), coreModule);
    // can't get moduleId & classLoaderFactory from module after releaseAll
    // so get moduleId & classLoaderFactory before releaseAll invoke
    coreModule.releaseAll();
    // 卸载所有导出的资源
    classLoaderService.unload(moduleId, classLoaderFactory);
    // 尝试关闭ClassLoader
    closeModuleJarClassLoaderIfNecessary(classLoaderFactory);
    return coreModule;
}
Also used : ClassLoaderFactory(com.shulie.instrument.simulator.core.classloader.ClassLoaderFactory)

Example 5 with ClassLoaderFactory

use of com.shulie.instrument.simulator.core.classloader.ClassLoaderFactory in project LinkAgent by shulieTech.

the class ModuleJarLoader method load.

void load(final SimulatorConfig simulatorConfig, final ModuleLoadCallback moduleLoadCallback) throws IOException {
    boolean hasModuleLoadedSuccessFlag = false;
    ClassLoaderFactory classLoaderFactory = null;
    if (isInfoEnabled) {
        logger.info("SIMULATOR: prepare loading module-jar={};", moduleJarFile);
    }
    try {
        classLoaderFactory = classLoaderService.getModuleClassLoaderFactory(moduleSpec.getModuleId());
        if (classLoaderFactory == null) {
            throw new SimulatorException("can't found ModuleClassLoaderFactory. moduleId=" + moduleSpec.getModuleId());
        }
        final ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
        ClassLoader moduleClassLoader = classLoaderFactory.getDefaultClassLoader();
        Thread.currentThread().setContextClassLoader(moduleClassLoader);
        try {
            hasModuleLoadedSuccessFlag = loadingModules(simulatorConfig, classLoaderFactory, moduleLoadCallback);
        } finally {
            Thread.currentThread().setContextClassLoader(contextClassLoader);
        }
    } finally {
        if (!hasModuleLoadedSuccessFlag && null != classLoaderFactory) {
            logger.warn("SIMULATOR: loading module-jar completed, but NONE module loaded, will be close ModuleClassLoader. module-jar={};", moduleJarFile);
            classLoaderFactory.release();
        }
    }
}
Also used : ClassLoaderFactory(com.shulie.instrument.simulator.core.classloader.ClassLoaderFactory) SimulatorException(com.shulie.instrument.simulator.core.exception.SimulatorException)

Aggregations

ClassLoaderFactory (com.shulie.instrument.simulator.core.classloader.ClassLoaderFactory)5 CoreModule (com.shulie.instrument.simulator.core.CoreModule)1 ClassLoaderFactoryImpl (com.shulie.instrument.simulator.core.classloader.impl.ClassLoaderFactoryImpl)1 SimulatorException (com.shulie.instrument.simulator.core.exception.SimulatorException)1 File (java.io.File)1 IOException (java.io.IOException)1