private void doDeployVerticle( boolean worker, boolean multiThreaded, final String main, final JsonObject config, final URL[] urls, int instances, File currentModDir, String includes, Handler<String> doneHandler) { checkWorkerContext(); // There is one module class loader per enclosing module + the name of the verticle. // If there is no enclosing module, there is one per top level verticle deployment // E.g. if a module A deploys "foo.js" as a verticle then all instances of foo.js deployed by // the enclosing // module will share a module class loader String depName = genDepName(); ModuleIdentifier enclosingModName = getEnclosingModID(); String moduleKey; if (enclosingModName == null) { // We are at the top level - just use the deployment name as the key moduleKey = createInternalModIDForVerticle(depName).toString(); } else { // Use the enclosing module name / or enclosing verticle PLUS the main moduleKey = enclosingModName.toString() + "#" + main; } ModuleReference mr = moduleRefs.get(moduleKey); if (mr == null) { mr = new ModuleReference( this, moduleKey, new ModuleClassLoader(platformClassLoader, urls), false); ModuleReference prev = moduleRefs.putIfAbsent(moduleKey, mr); if (prev != null) { mr = prev; } } if (includes != null) { loadIncludedModules(currentModDir, mr, includes); } doDeploy( depName, false, worker, multiThreaded, main, null, config, urls, instances, currentModDir, mr, doneHandler); }
private File locateModule(File currentModDir, ModuleIdentifier modID) { if (currentModDir != null) { // Nested moduleRefs - look inside current module dir File modDir = new File(new File(currentModDir, LOCAL_MODS_DIR), modID.toString()); if (modDir.exists()) { return modDir; } } File modDir = new File(modRoot, modID.toString()); if (modDir.exists()) { return modDir; } else if (!systemModRoot.equals(modRoot)) { modDir = new File(systemModRoot, modID.toString()); if (modDir.exists()) { return modDir; } } return null; }
public void deployModuleFromZip( String zipFileName, JsonObject config, int instances, Handler<String> doneHandler) { final String modName = zipFileName.substring(0, zipFileName.length() - 4); ModuleIdentifier modID = new ModuleIdentifier("__vertx_tmp#" + modName + "#__vertx_tmp"); if (unzipModule(modID, new ModuleZipInfo(false, zipFileName), false)) { deployModule(modID.toString(), config, instances, doneHandler); } else { doneHandler.handle(null); } }
private boolean unzipModule( final ModuleIdentifier modID, final ModuleZipInfo zipInfo, boolean deleteZip) { // We synchronize to prevent a race whereby it tries to unzip the same module at the // same time (e.g. deployModule for the same module name has been called in parallel) String modName = modID.toString(); synchronized (modName.intern()) { if (!checkModDirs()) { return false; } File fdest = new File(modRoot, modName); File sdest = new File(systemModRoot, modName); if (fdest.exists() || sdest.exists()) { // This can happen if the same module is requested to be installed // at around the same time // It's ok if this happens log.warn("Module " + modID + " is already installed"); return true; } // Unzip into temp dir first File tdest = unzipIntoTmpDir(zipInfo, deleteZip); if (tdest == null) { return false; } // Check if it's a system module JsonObject conf = loadModuleConfig(modID, tdest); ModuleFields fields = new ModuleFields(conf); boolean system = fields.isSystem(); // Now copy it to the proper directory String moveFrom = tdest.getAbsolutePath(); try { vertx .fileSystem() .moveSync(moveFrom, system ? sdest.getAbsolutePath() : fdest.getAbsolutePath()); } catch (Exception e) { log.error("Failed to move module", e); return false; } log.info("Module " + modID + " successfully installed"); return true; } }
private boolean doPullInDependencies(File modRoot, ModuleIdentifier modID) { File modDir = new File(modRoot, modID.toString()); if (!modDir.exists()) { log.error("Cannot find module to uninstall"); } JsonObject conf = loadModuleConfig(modID, modDir); if (conf == null) { log.error("Module " + modID + " does not contain a mod.json"); } ModuleFields fields = new ModuleFields(conf); List<String> mods = new ArrayList<>(); String includes = fields.getIncludes(); if (includes != null) { mods.addAll(Arrays.asList(parseIncludeString(includes))); } String deploys = fields.getDeploys(); if (deploys != null) { mods.addAll(Arrays.asList(parseIncludeString(deploys))); } if (!mods.isEmpty()) { File internalModsDir = new File(modDir, "mods"); if (!internalModsDir.exists()) { internalModsDir.mkdir(); } for (String modName : mods) { File internalModDir = new File(internalModsDir, modName); if (!internalModDir.exists()) { ModuleIdentifier theModID = new ModuleIdentifier(modName); ModuleZipInfo zipInfo = getModule(theModID); if (zipInfo.filename != null) { internalModDir.mkdir(); if (!unzipModuleData(internalModDir, zipInfo, true)) { return false; } else { log.info("Module " + modName + " successfully installed in mods dir of " + modName); // Now recurse so we bring in all of the deps doPullInDependencies(internalModsDir, theModID); } } } } } return true; }
private void doDeployMod( final boolean redeploy, final String depName, final ModuleIdentifier modID, final JsonObject config, final int instances, final File currentModDir, final Handler<String> doneHandler) { checkWorkerContext(); File modDir = locateModule(currentModDir, modID); if (modDir != null) { JsonObject conf = loadModuleConfig(modID, modDir); ModuleFields fields = new ModuleFields(conf); String main = fields.getMain(); if (main == null) { log.error("Runnable module " + modID + " mod.json must contain a \"main\" field"); callDoneHandler(doneHandler, null); return; } boolean worker = fields.isWorker(); boolean multiThreaded = fields.isMultiThreaded(); if (multiThreaded && !worker) { throw new IllegalArgumentException("Multi-threaded modules must be workers"); } boolean preserveCwd = fields.isPreserveCurrentWorkingDirectory(); // If preserveCwd then use the current module directory instead, or the cwd if not in a module File modDirToUse = preserveCwd ? currentModDir : modDir; List<URL> urls = getModuleClasspath(modDir); if (urls == null) { callDoneHandler(doneHandler, null); return; } ModuleReference mr = moduleRefs.get(modID.toString()); if (mr == null) { boolean res = fields.isResident(); mr = new ModuleReference( this, modID.toString(), new ModuleClassLoader(platformClassLoader, urls.toArray(new URL[urls.size()])), res); ModuleReference prev = moduleRefs.putIfAbsent(modID.toString(), mr); if (prev != null) { mr = prev; } } ModuleIdentifier enclosingModID = getEnclosingModID(); if (enclosingModID != null) { // If enclosed in another module then the enclosing module classloader becomes a parent of // this one ModuleReference parentRef = moduleRefs.get(enclosingModID.toString()); mr.mcl.addParent(parentRef); parentRef.incRef(); } // Now load any included moduleRefs String includes = fields.getIncludes(); if (includes != null) { if (!loadIncludedModules(modDir, mr, includes)) { callDoneHandler(doneHandler, null); return; } } final boolean autoRedeploy = fields.isAutoRedeploy(); doDeploy( depName, autoRedeploy, worker, multiThreaded, main, modID, config, urls.toArray(new URL[urls.size()]), instances, modDirToUse, mr, new Handler<String>() { @Override public void handle(String deploymentID) { if (deploymentID != null && !redeploy && autoRedeploy) { redeployer.moduleDeployed(deployments.get(deploymentID)); } callDoneHandler(doneHandler, deploymentID); } }); } else { if (doInstallMod(modID)) { doDeployMod(redeploy, depName, modID, config, instances, currentModDir, doneHandler); } else { callDoneHandler(doneHandler, null); } } }