private boolean loadIncludedModules( File currentModuleDir, ModuleReference mr, String includesString) { checkWorkerContext(); for (String moduleName : parseIncludeString(includesString)) { ModuleIdentifier modID = new ModuleIdentifier(moduleName); ModuleReference includedMr = moduleRefs.get(moduleName); if (includedMr == null) { File modDir = locateModule(currentModuleDir, modID); if (modDir == null) { if (!doInstallMod(modID)) { return false; } } modDir = locateModule(currentModuleDir, modID); List<URL> urls = getModuleClasspath(modDir); JsonObject conf = loadModuleConfig(modID, modDir); ModuleFields fields = new ModuleFields(conf); boolean res = fields.isResident(); includedMr = new ModuleReference( this, moduleName, new ModuleClassLoader(platformClassLoader, urls.toArray(new URL[urls.size()])), res); ModuleReference prev = moduleRefs.putIfAbsent(moduleName, includedMr); if (prev != null) { includedMr = prev; } String includes = fields.getIncludes(); if (includes != null) { loadIncludedModules(modDir, includedMr, includes); } } includedMr.incRef(); mr.mcl.addParent(includedMr); } return true; }
private void clearParents() { for (ModuleReference parent : parents) { parent.decRef(); } parents.clear(); }
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); } } }
private void doDeploy( final String depName, boolean autoRedeploy, boolean worker, boolean multiThreaded, String theMain, final ModuleIdentifier modID, final JsonObject config, final URL[] urls, int instances, final File modDir, final ModuleReference mr, final Handler<String> doneHandler) { checkWorkerContext(); final String deploymentName = depName != null ? depName : genDepName(); log.debug( "Deploying name : " + deploymentName + " main: " + theMain + " instances: " + instances); // How we determine which language implementation to use: // 1. Look for a prefix on the main, e.g. 'groovy:org.foo.myproject.MyGroovyMain' would force // the groovy // language impl to be used // 2. If there is no prefix, then look at the extension, if any. If there is an extension // mapping for that // extension, use that. // 3. No prefix and no extension mapping - use the default runtime LanguageImplInfo langImplInfo = null; final String main; // Look for a prefix int prefixMarker = theMain.indexOf(COLON); if (prefixMarker != -1) { String prefix = theMain.substring(0, prefixMarker); langImplInfo = languageImpls.get(prefix); if (langImplInfo == null) { throw new IllegalStateException("No language implementation known for prefix " + prefix); } main = theMain.substring(prefixMarker + 1); } else { main = theMain; } if (langImplInfo == null) { // No prefix - now look at the extension int extensionMarker = main.lastIndexOf('.'); if (extensionMarker != -1) { String extension = main.substring(extensionMarker + 1); String langImplName = extensionMappings.get(extension); if (langImplName != null) { langImplInfo = languageImpls.get(langImplName); if (langImplInfo == null) { throw new IllegalStateException( "Extension mapping for " + extension + " specified as " + langImplName + ", but no language implementation known for that name"); } } } } if (langImplInfo == null) { // Use the default langImplInfo = languageImpls.get(defaultLanguageImplName); if (langImplInfo == null) { throw new IllegalStateException( "Default language implementation is " + defaultLanguageImplName + " but no language implementation known for that name"); } } // Include the language impl module as a parent of the classloader if (langImplInfo.moduleName != null) { if (!loadIncludedModules(modDir, mr, langImplInfo.moduleName)) { log.error("Failed to load module: " + langImplInfo.moduleName); doneHandler.handle(null); return; } } final VerticleFactory verticleFactory; final Container container = new DefaultContainer(this); try { // TODO not one verticle factory per module ref, but one per language per module ref verticleFactory = mr.getVerticleFactory(langImplInfo.factoryName, vertx, container); } catch (Exception e) { log.error("Failed to instantiate verticle factory", e); doneHandler.handle(null); return; } final int instCount = instances; class AggHandler { AtomicInteger count = new AtomicInteger(0); boolean failed; void done(boolean res) { if (!res) { failed = true; } if (count.incrementAndGet() == instCount) { String deploymentID = failed ? null : deploymentName; callDoneHandler(doneHandler, deploymentID); } } } final AggHandler aggHandler = new AggHandler(); String parentDeploymentName = getDeploymentName(); final Deployment deployment = new Deployment( deploymentName, main, modID, instances, config == null ? new JsonObject() : config.copy(), urls, modDir, parentDeploymentName, mr, autoRedeploy); mr.incRef(); deployments.put(deploymentName, deployment); if (parentDeploymentName != null) { Deployment parentDeployment = deployments.get(parentDeploymentName); parentDeployment.childDeployments.add(deploymentName); } ClassLoader oldTCCL = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(mr.mcl); try { for (int i = 0; i < instances; i++) { // Launch the verticle instance Runnable runner = new Runnable() { public void run() { Verticle verticle = null; boolean error = true; try { verticle = verticleFactory.createVerticle(main); error = false; } catch (ClassNotFoundException e) { log.error( "Cannot find verticle " + main + " in " + verticleFactory.getClass().getName(), e); } catch (Throwable t) { log.error( "Failed to create verticle " + main + " in " + verticleFactory.getClass().getName(), t); } if (error) { doUndeploy( deploymentName, new SimpleHandler() { public void handle() { aggHandler.done(false); } }); return; } verticle.setContainer(container); verticle.setVertx(vertx); try { addVerticle(deployment, verticle, verticleFactory); if (modDir != null) { setPathAdjustment(modDir); } VoidResult vr = new VoidResult(); verticle.start(vr); vr.setHandler( new AsyncResultHandler<Void>() { @Override public void handle(AsyncResult<Void> ar) { if (ar.succeeded()) { aggHandler.done(true); } else { log.error( "Failed to deploy verticle " + main + " in " + verticleFactory.getClass().getName(), ar.exception); aggHandler.done(false); } } }); } catch (Throwable t) { t.printStackTrace(); vertx.reportException(t); doUndeploy( deploymentName, new SimpleHandler() { public void handle() { aggHandler.done(false); } }); } } }; if (worker) { vertx.startInBackground(runner, multiThreaded); } else { vertx.startOnEventLoop(runner); } } } finally { Thread.currentThread().setContextClassLoader(oldTCCL); } }