From 0b8545e48796a0922f3a0680aa53e29d70b3cb03 Mon Sep 17 00:00:00 2001 From: Manolo Carrasco Date: Thu, 3 Apr 2014 17:05:47 +0200 Subject: [PATCH] DevelopmentServletLoader: Reload servlet container - Add a couple of parameters in order make jetty context reload whenever a class is modified. - Remove deprecated SSL API calls. Change-Id: I737fb92e78ce5573a4473639f25fcdad606f3c55 --- eclipse/Development Server (vaadin).launch | 1 + .../launcher/DevelopmentServerLauncher.java | 90 +++++++++++++++++-- 2 files changed, 82 insertions(+), 9 deletions(-) diff --git a/eclipse/Development Server (vaadin).launch b/eclipse/Development Server (vaadin).launch index 9505811c0b..197344cce0 100644 --- a/eclipse/Development Server (vaadin).launch +++ b/eclipse/Development Server (vaadin).launch @@ -14,6 +14,7 @@ + diff --git a/uitest/src/com/vaadin/launcher/DevelopmentServerLauncher.java b/uitest/src/com/vaadin/launcher/DevelopmentServerLauncher.java index d02c609a0b..d94518ca9c 100644 --- a/uitest/src/com/vaadin/launcher/DevelopmentServerLauncher.java +++ b/uitest/src/com/vaadin/launcher/DevelopmentServerLauncher.java @@ -17,15 +17,20 @@ package com.vaadin.launcher; import java.io.File; +import java.io.FilenameFilter; import java.io.IOException; import java.io.OutputStream; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; +import java.net.URL; +import java.net.URLClassLoader; import java.text.SimpleDateFormat; +import java.util.ArrayList; import java.util.Calendar; import java.util.EnumSet; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -43,6 +48,8 @@ import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.nio.SelectChannelConnector; import org.eclipse.jetty.server.ssl.SslSocketConnector; +import org.eclipse.jetty.util.Scanner; +import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.webapp.WebAppContext; import com.vaadin.launcher.util.BrowserLauncher; @@ -70,6 +77,7 @@ public class DevelopmentServerLauncher { assertAssertionsEnabled(); + // // Pass-through of arguments for Jetty final Map serverArgs = parseArguments(args); if (!serverArgs.containsKey("shutdownPort")) { @@ -160,19 +168,18 @@ public class DevelopmentServerLauncher { if (serverArgs.containsKey("withssl")) { final SslSocketConnector sslConnector = new SslSocketConnector(); sslConnector.setPort(8444); - sslConnector.setTruststore(KEYSTORE); - sslConnector.setTrustPassword("password"); - sslConnector.setKeystore(KEYSTORE); - sslConnector.setKeyPassword("password"); - sslConnector.setPassword("password"); + SslContextFactory sslFact = sslConnector.getSslContextFactory(); + sslFact.setTrustStore(KEYSTORE); + sslFact.setTrustStorePassword("password"); + sslFact.setKeyStorePath(KEYSTORE); + sslFact.setKeyManagerPassword("password"); + sslFact.setKeyStorePassword("password"); server.setConnectors(new Connector[] { connector, sslConnector }); } else { server.setConnectors(new Connector[] { connector }); } final WebAppContext webappcontext = new WebAppContext(); - String path = DevelopmentServerLauncher.class.getPackage().getName() - .replace(".", File.separator); webappcontext.setContextPath(serverArgs.get("context")); webappcontext.setWar(serverArgs.get("webroot")); server.setHandler(webappcontext); @@ -198,6 +205,73 @@ public class DevelopmentServerLauncher { } } + // --autoreload=all --autoreload=WebContent/classes,other/path + // --scaninterval=1 + // Configure Jetty to auto-reload when a any class is compiled in + // any folder included in the list of folders passed as arguments + // or in the entire classpath if the keyworkd all is passed. + if (serverArgs.containsKey("autoreload")) { + int interval = 1; + if (serverArgs.containsKey("scaninterval")) { + interval = Integer.parseInt(serverArgs.get("scaninterval")); + } + + List classFolders = new ArrayList(); + String[] paths = serverArgs.get("autoreload").split(","); + if (paths.length == 1 && "all".equals(paths[0])) { + ClassLoader cl = server.getClass().getClassLoader(); + for (URL u : ((URLClassLoader) cl).getURLs()) { + File f = new File(u.getPath()); + if (f.isDirectory()) { + classFolders.add(f); + } + } + } else { + for (String p : paths) { + File f = new File(p); + if (f.isDirectory()) { + classFolders.add(f); + } + } + } + if (!classFolders.isEmpty()) { + System.out + .println("Enabling context auto-reload.\n Scan interval: " + + interval + " secs.\n Scanned folders: "); + for (File f : classFolders) { + System.out.println(" " + f.getAbsolutePath()); + webappcontext.setExtraClasspath(f.getAbsolutePath()); + } + System.out.println(""); + + Scanner scanner = new Scanner(); + scanner.setScanInterval(interval); + + scanner.setRecursive(true); + scanner.addListener(new Scanner.BulkListener() { + @Override + public void filesChanged(List filenames) + throws Exception { + webappcontext.stop(); + server.stop(); + webappcontext.start(); + server.start(); + } + }); + scanner.setReportExistingFilesOnStartup(false); + scanner.setFilenameFilter(new FilenameFilter() { + @Override + public boolean accept(File folder, String name) { + return name.endsWith(".class"); + } + }); + + scanner.setScanDirs(classFolders); + scanner.start(); + server.getContainer().addBean(scanner); + } + } + try { server.start(); @@ -380,7 +454,6 @@ public class DevelopmentServerLauncher { public void destroy() { // TODO Auto-generated method stub } - } private static void dumpThreadStacks() { @@ -395,7 +468,6 @@ public class DevelopmentServerLauncher { } System.out.println(); } - } } -- 2.39.5