/** Detect sources modifications */ public static synchronized void detectChanges() { if (mode == Mode.PROD) { return; } try { pluginCollection.beforeDetectingChanges(); if (!pluginCollection.detectClassesChange()) { classloader.detectChanges(); } Router.detectChanges(ctxPath); for (VirtualFile conf : confs) { if (conf.lastModified() > startedAt) { start(); return; } } pluginCollection.detectChange(); if (!Play.started) { throw new RuntimeException("Not started"); } } catch (PlayException e) { throw e; } catch (Exception e) { // We have to do a clean refresh start(); } }
/** Start the application. Recall to restart ! */ public static synchronized void start() { try { if (started) { stop(); } if (standalonePlayServer) { // Can only register shutdown-hook if running as standalone server if (!shutdownHookEnabled) { // registers shutdown hook - Now there's a good chance that we can notify // our plugins that we're going down when some calls ctrl+c or just kills our process.. shutdownHookEnabled = true; Runtime.getRuntime() .addShutdownHook( new Thread() { public void run() { Play.stop(); } }); } } if (mode == Mode.DEV) { // Need a new classloader classloader = new ApplicationClassloader(); // Put it in the current context for any code that relies on having it there Thread.currentThread().setContextClassLoader(classloader); // Reload plugins pluginCollection.reloadApplicationPlugins(); } // Reload configuration readConfiguration(); // Configure logs String logLevel = configuration.getProperty("application.log", "INFO"); // only override log-level if Logger was not configured manually if (!Logger.configuredManually) { Logger.setUp(logLevel); } Logger.recordCaller = Boolean.parseBoolean(configuration.getProperty("application.log.recordCaller", "false")); // Locales langs = new ArrayList<String>( Arrays.asList(configuration.getProperty("application.langs", "").split(","))); if (langs.size() == 1 && langs.get(0).trim().length() == 0) { langs = new ArrayList<String>(16); } // Clean templates TemplateLoader.cleanCompiledCache(); // SecretKey secretKey = configuration.getProperty("application.secret", "").trim(); if (secretKey.length() == 0) { Logger.warn("No secret key defined. Sessions will not be encrypted"); } // Default web encoding String _defaultWebEncoding = configuration.getProperty("application.web_encoding"); if (_defaultWebEncoding != null) { Logger.info("Using custom default web encoding: " + _defaultWebEncoding); defaultWebEncoding = _defaultWebEncoding; // Must update current response also, since the request/response triggering // this configuration-loading in dev-mode have already been // set up with the previous encoding if (Http.Response.current() != null) { Http.Response.current().encoding = _defaultWebEncoding; } } // Try to load all classes Play.classloader.getAllClasses(); // Routes Router.detectChanges(ctxPath); // Cache Cache.init(); // Plugins try { pluginCollection.onApplicationStart(); } catch (Exception e) { if (Play.mode.isProd()) { Logger.error(e, "Can't start in PROD mode with errors"); } if (e instanceof RuntimeException) { throw (RuntimeException) e; } throw new UnexpectedException(e); } if (firstStart) { Logger.info( "Application '%s' is now started !", configuration.getProperty("application.name", "")); firstStart = false; } // We made it started = true; startedAt = System.currentTimeMillis(); // Plugins pluginCollection.afterApplicationStart(); } catch (PlayException e) { started = false; try { Cache.stop(); } catch (Exception ignored) { } throw e; } catch (Exception e) { started = false; try { Cache.stop(); } catch (Exception ignored) { } throw new UnexpectedException(e); } }