Browse Source

jfinal 3.5 release ^_^

James 7 years ago
parent
commit
94d22d8fe0

+ 16 - 7
pom.xml

@@ -52,10 +52,17 @@
 			<version>4.8.2</version>
 			<scope>test</scope>
 		</dependency>
+		
+		<dependency>
+			<groupId>cglib</groupId>
+			<artifactId>cglib-nodep</artifactId>
+			<version>3.2.5</version>
+		</dependency>
+		
 		<dependency>
 			<groupId>com.jfinal</groupId>
 			<artifactId>jetty-server</artifactId>
-			<version>8.1.8</version>
+			<version>2018.9</version>
 			<scope>provided</scope>
 		</dependency>
 		<!-- dependency>
@@ -65,12 +72,19 @@
 			<scope>provided</scope>
 		</dependency -->
 		<!-- jsp support by jetty -->
-		<dependency>
+		<!-- dependency>
 			<groupId>org.eclipse.jetty</groupId>
 			<artifactId>jetty-jsp</artifactId>
 			<version>8.1.8.v20121106</version>
 			<scope>provided</scope>
+		</dependency -->
+		<dependency>
+			<groupId>org.eclipse.jetty</groupId>
+			<artifactId>jetty-jsp</artifactId>
+			<version>9.2.26.v20180806</version>
+			<scope>provided</scope>
 		</dependency>
+		
 		<dependency>
 			<groupId>com.mchange</groupId>
 			<artifactId>c3p0</artifactId>
@@ -133,11 +147,6 @@
 			<scope>provided</scope>
 		</dependency>
 		<dependency>
-			<groupId>cglib</groupId>
-			<artifactId>cglib-nodep</artifactId>
-			<version>3.2.5</version>
-		</dependency>
-		<dependency>
 			<groupId>redis.clients</groupId>
 			<artifactId>jedis</artifactId>
 			<version>2.7.2</version>

+ 7 - 8
src/main/java/com/jfinal/core/JFinal.java

@@ -26,9 +26,7 @@ import com.jfinal.kit.LogKit;
 import com.jfinal.kit.PathKit;
 import com.jfinal.plugin.IPlugin;
 import com.jfinal.render.RenderManager;
-import com.jfinal.server.JettyServerForIDEA;
 import com.jfinal.server.IServer;
-import com.jfinal.server.ServerFactory;
 import com.jfinal.token.ITokenCache;
 import com.jfinal.token.TokenManager;
 import com.jfinal.upload.OreillyCos;
@@ -150,7 +148,7 @@ public final class JFinal {
 	}
 	
 	public static void start() {
-		server = ServerFactory.getServer();
+		server = com.jfinal.server.jetty.ServerFactory.getServer();
 		server.start();
 	}
 	
@@ -158,7 +156,7 @@ public final class JFinal {
 	 * 用于在 Eclipse 中,通过创建 main 方法的方式启动项目,支持热加载
 	 */
 	public static void start(String webAppDir, int port, String context, int scanIntervalSeconds) {
-		server = ServerFactory.getServer(webAppDir, port, context, scanIntervalSeconds);
+		server = com.jfinal.server.jetty.ServerFactory.getServer(webAppDir, port, context, scanIntervalSeconds);
 		server.start();
 	}
 	
@@ -179,8 +177,9 @@ public final class JFinal {
 	 */
 	@Deprecated
 	public static void start(String webAppDir, int port, String context) {
-		server = new JettyServerForIDEA(webAppDir, port, context);
-		server.start();
+		// server = new JettyServerForIDEA(webAppDir, port, context);
+		// server.start();
+		start(webAppDir, port, context, 0);
 	}
 	
 	public static void stop() {
@@ -194,7 +193,7 @@ public final class JFinal {
 	 */
 	public static void main(String[] args) {
 		if (args == null || args.length == 0) {
-			server = ServerFactory.getServer();
+			server = com.jfinal.server.jetty.ServerFactory.getServer();
 			server.start();
 			return ;
 		}
@@ -205,7 +204,7 @@ public final class JFinal {
 			int port = Integer.parseInt(args[1]);
 			String context = args[2];
 			int scanIntervalSeconds = Integer.parseInt(args[3]);
-			server = ServerFactory.getServer(webAppDir, port, context, scanIntervalSeconds);
+			server = com.jfinal.server.jetty.ServerFactory.getServer(webAppDir, port, context, scanIntervalSeconds);
 			server.start();
 			return ;
 		}

+ 0 - 87
src/main/java/com/jfinal/server/JFinalClassLoader.java

@@ -1,87 +0,0 @@
-/**
- * Copyright (c) 2011-2019, James Zhan 詹波 (jfinal@126.com).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.jfinal.server;
-
-import java.io.File;
-import java.io.IOException;
-import org.eclipse.jetty.util.resource.Resource;
-import org.eclipse.jetty.webapp.WebAppClassLoader;
-import org.eclipse.jetty.webapp.WebAppContext;
-
-/**
- * JFinalClassLoader
- */
-class JFinalClassLoader extends WebAppClassLoader {
-	private boolean initialized = false;
-	
-	public JFinalClassLoader(WebAppContext context, String classPath) throws IOException {
-		super(context);
-		if(classPath != null){
-			String[] tokens = classPath.split(String.valueOf(File.pathSeparatorChar));
-			for(String entry : tokens){
-				String path = entry;
-				if(path.startsWith("-y-") || path.startsWith("-n-")) {
-					path = path.substring(3);
-				}
-				
-				if(entry.startsWith("-n-") == false){
-					super.addClassPath(path);
-				}
-			}
-		}
-		
-		initialized = true;
-	}
-	
-	@SuppressWarnings({"unchecked", "rawtypes"})
-	public Class loadClass(String name) throws ClassNotFoundException {
-		try {
-			
-			// 使用 WebAppContext.addSystemClass("sun.") 代替下面的方案更高效
-			// java.lang.IllegalAccessError: class sun.reflect.GeneratedConstructorAccessor2 cannot access its superclass sun.reflect.ConstructorAccessorImpl
-			// if (name.startsWith("sun.") || name.startsWith("com.sun.")) {
-				// return getParent().loadClass(name);
-			// }
-			
-			return loadClass(name, false);
-		}
-		catch (NoClassDefFoundError e) {
-			throw new ClassNotFoundException(name);
-		}
-	}
-	
-	public void addClassPath(String classPath) throws IOException {
-		if (initialized) {
-			if (!classPath.endsWith("WEB-INF/classes/"))
-				return;
-		}
-		super.addClassPath(classPath);
-	}
-	
-	public void addJars(Resource jars) {
-		if (initialized) {
-			return;
-		}
-		super.addJars(jars);
-	}
-}
-
-
-
-
-
-

+ 0 - 232
src/main/java/com/jfinal/server/JettyServer.java

@@ -1,232 +0,0 @@
-/**
- * Copyright (c) 2011-2019, James Zhan 詹波 (jfinal@126.com).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.jfinal.server;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.DatagramSocket;
-import java.net.ServerSocket;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.SessionManager;
-import org.eclipse.jetty.server.nio.SelectChannelConnector;
-import org.eclipse.jetty.server.session.HashSessionManager;
-import org.eclipse.jetty.server.session.SessionHandler;
-import org.eclipse.jetty.webapp.WebAppContext;
-import com.jfinal.core.Const;
-import com.jfinal.kit.FileKit;
-import com.jfinal.kit.LogKit;
-import com.jfinal.kit.PathKit;
-import com.jfinal.kit.StrKit;
-
-/**
- * JettyServer is used to config and start jetty web server.
- * Jetty version 8.1.8
- */
-class JettyServer implements IServer {
-	
-	private String webAppDir;
-	private int port;
-	private String context;
-	private int scanIntervalSeconds;
-	private boolean running = false;
-	private Server server;
-	private WebAppContext webApp;
-	
-	JettyServer(String webAppDir, int port, String context, int scanIntervalSeconds) {
-		if (webAppDir == null) {
-			throw new IllegalStateException("Invalid webAppDir of web server: " + webAppDir);
-		}
-		if (port < 0 || port > 65535) {
-			throw new IllegalArgumentException("Invalid port of web server: " + port);
-		}
-		if (StrKit.isBlank(context)) {
-			throw new IllegalStateException("Invalid context of web server: " + context);
-		}
-		
-		this.webAppDir = webAppDir;
-		this.port = port;
-		this.context = context;
-		this.scanIntervalSeconds = scanIntervalSeconds;
-	}
-	
-	public void start() {
-		if (!running) {
-			try {
-				running = true;
-				doStart();
-			} catch (Exception e) {
-				System.err.println(e.getMessage());
-				LogKit.error(e.getMessage(), e);
-			}
-		}
-	}
-	
-	public void stop() {
-		if (running) {
-			try {server.stop();} catch (Exception e) {LogKit.error(e.getMessage(), e);}
-			running = false;
-		}
-	}
-	
-	private void doStart() {
-		if (!available(port)) {
-			throw new IllegalStateException("port: " + port + " already in use!");
-		}
-		
-		deleteSessionData();
-		
-		System.out.println("Starting JFinal " + Const.JFINAL_VERSION);
-		server = new Server();
-		SelectChannelConnector connector = new SelectChannelConnector();
-		connector.setPort(port);
-		server.addConnector(connector);
-		webApp = new WebAppContext();
-		
-		webApp.addSystemClass("sun.");
-		webApp.addSystemClass("com.sun.");
-		
-		webApp.setThrowUnavailableOnStartupException(true);	// 在启动过程中允许抛出异常终止启动并退出 JVM
-		webApp.setContextPath(context);
-		webApp.setResourceBase(webAppDir);	// webApp.setWar(webAppDir);
-		webApp.setInitParameter("org.eclipse.jetty.servlet.Default.dirAllowed", "false");
-		webApp.setInitParameter("org.eclipse.jetty.servlet.Default.useFileMappedBuffer", "false");	// webApp.setInitParams(Collections.singletonMap("org.mortbay.jetty.servlet.Default.useFileMappedBuffer", "false"));
-		persistSession(webApp);
-		
-		server.setHandler(webApp);
-		
-		// configureScanner
-		if (scanIntervalSeconds > 0) {
-		    //only need to change classloader when scanIntervalSeconds > 0
-            changeClassLoader(webApp);
-            
-			Scanner scanner = new Scanner(PathKit.getRootClassPath(), scanIntervalSeconds) {
-				public void onChange() {
-					try {
-						System.err.println("\nLoading changes ......");
-						webApp.stop();
-						JFinalClassLoader loader = new JFinalClassLoader(webApp, getClassPath());
-						webApp.setClassLoader(loader);
-						webApp.start();
-						System.err.println("Loading complete.");
-					} catch (Exception e) {
-						System.err.println("Error reconfiguring/restarting webapp after change in watched files");
-						LogKit.error(e.getMessage(), e);
-					}
-				}
-			};
-			System.out.println("Starting scanner at interval of " + scanIntervalSeconds + " seconds.");
-			scanner.start();
-		}
-		
-		try {
-			System.out.println("Starting web server on port: " + port);
-			server.start();
-			System.out.println("Starting Complete. Welcome To The JFinal World :)");
-			server.join();
-		} catch (Exception e) {
-			LogKit.error(e.getMessage(), e);
-			System.exit(100);
-		}
-		return;
-	}
-	
-	private void changeClassLoader(WebAppContext webApp) {
-		try {
-			String classPath = getClassPath();
-			JFinalClassLoader jfcl = new JFinalClassLoader(webApp, classPath);
-			// jfcl.addClassPath(classPath);
-			webApp.setClassLoader(jfcl);
-		} catch (IOException e) {
-			LogKit.error(e.getMessage(), e);
-		}
-	}
-	
-	private String getClassPath() {
-		return System.getProperty("java.class.path");
-	}
-	
-	private void deleteSessionData() {
-		try {
-			FileKit.delete(new File(getStoreDir()));
-		}
-		catch (Exception e) {
-			LogKit.logNothing(e);
-		}
-	}
-	
-	private String getStoreDir() {
-		String storeDir = PathKit.getWebRootPath() + "/../../session_data" + context;
-		if ("\\".equals(File.separator)) {
-			storeDir = storeDir.replaceAll("/", "\\\\");
-		}
-		return storeDir;
-	}
-	
-	private void persistSession(WebAppContext webApp) {
-		String storeDir = getStoreDir();
-		
-		SessionManager sm = webApp.getSessionHandler().getSessionManager();
-		if (sm instanceof HashSessionManager) {
-			((HashSessionManager)sm).setStoreDirectory(new File(storeDir));
-			return ;
-		}
-		
-		HashSessionManager hsm = new HashSessionManager();
-		hsm.setStoreDirectory(new File(storeDir));
-		SessionHandler sh = new SessionHandler();
-		sh.setSessionManager(hsm);
-		webApp.setSessionHandler(sh);
-	}
-	
-	private static boolean available(int port) {
-		if (port <= 0) {
-			throw new IllegalArgumentException("Invalid start port: " + port);
-		}
-		
-		ServerSocket ss = null;
-		DatagramSocket ds = null;
-		try {
-			ss = new ServerSocket(port);
-			ss.setReuseAddress(true);
-			ds = new DatagramSocket(port);
-			ds.setReuseAddress(true);
-			return true;
-		} catch (IOException e) {
-			LogKit.logNothing(e);
-		} finally {
-			if (ds != null) {
-				ds.close();
-			}
-			
-			if (ss != null) {
-				try {
-					ss.close();
-				} catch (IOException e) {
-					// should not be thrown, just detect port available.
-					LogKit.logNothing(e);
-				}
-			}
-		}
-		return false;
-	}
-}
-
-
-
-
-
-

+ 0 - 237
src/main/java/com/jfinal/server/JettyServerForIDEA.java

@@ -1,237 +0,0 @@
-/**
- * Copyright (c) 2011-2019, James Zhan 詹波 (jfinal@126.com).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.jfinal.server;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.DatagramSocket;
-import java.net.ServerSocket;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.SessionManager;
-import org.eclipse.jetty.server.nio.SelectChannelConnector;
-import org.eclipse.jetty.server.session.HashSessionManager;
-import org.eclipse.jetty.server.session.SessionHandler;
-import org.eclipse.jetty.webapp.WebAppContext;
-import com.jfinal.core.Const;
-import com.jfinal.kit.FileKit;
-import com.jfinal.kit.LogKit;
-import com.jfinal.kit.PathKit;
-import com.jfinal.kit.StrKit;
-
-/**
- * jfinal 3.5 更新(2018-09-01):
- * 		由于 jfinal 3.5 解决了 IDEA 下 JFinal.start(四个参数) 无法启动的问题,
- * 		此类已被废弃,建议使用 JFinal.start(四个参数) 带四个参数的 start()
- * 		方法来启动项目,IDEA 下也支持热加载,注意要先配置自动编译,jfinal 是
- * 		通过监测被编译的 class 文件的修改来触发热加载的
- * 
- * 
- * 
- * IDEA 专用于在 IDEA 之下用 main 方法启动,原启动方式在 IDEA 下会报异常
- * 注意:用此方法启动对热加载支持不完全,只支持方法内部修改的热加载,不支持添加、删除方法
- *      不支持添加类文件热加载,建议开发者在 IDEA 下使用 jrebel 或者 maven 下的 jetty
- *      插件支持列为完全的热加载
- */
-@Deprecated
-public class JettyServerForIDEA implements IServer {
-	
-	private String webAppDir;
-	private int port;
-	private String context;
-	// private int scanIntervalSeconds;
-	private boolean running = false;
-	private Server server;
-	private WebAppContext webApp;
-	
-	public JettyServerForIDEA(String webAppDir, int port, String context) {
-		if (webAppDir == null) {
-			throw new IllegalStateException("Invalid webAppDir of web server: " + webAppDir);
-		}
-		if (port < 0 || port > 65535) {
-			throw new IllegalArgumentException("Invalid port of web server: " + port);
-		}
-		if (StrKit.isBlank(context)) {
-			throw new IllegalStateException("Invalid context of web server: " + context);
-		}
-		
-		this.webAppDir = webAppDir;
-		this.port = port;
-		this.context = context;
-		// this.scanIntervalSeconds = scanIntervalSeconds;
-	}
-	
-	public void start() {
-		if (!running) {
-			try {
-				running = true;
-				doStart();
-			} catch (Exception e) {
-				System.err.println(e.getMessage());
-				LogKit.error(e.getMessage(), e);
-			}
-		}
-	}
-	
-	public void stop() {
-		if (running) {
-			try {server.stop();} catch (Exception e) {LogKit.error(e.getMessage(), e);}
-			running = false;
-		}
-	}
-	
-	private void doStart() {
-		if (!available(port)) {
-			throw new IllegalStateException("port: " + port + " already in use!");
-		}
-		
-		deleteSessionData();
-		
-		System.out.println("Starting JFinal " + Const.JFINAL_VERSION);
-		server = new Server();
-		SelectChannelConnector connector = new SelectChannelConnector();
-		connector.setPort(port);
-		server.addConnector(connector);
-		webApp = new WebAppContext();
-		webApp.setThrowUnavailableOnStartupException(true);	// 在启动过程中允许抛出异常终止启动并退出 JVM
-		webApp.setContextPath(context);
-		webApp.setResourceBase(webAppDir);	// webApp.setWar(webAppDir);
-		webApp.setInitParameter("org.eclipse.jetty.servlet.Default.dirAllowed", "false");
-		webApp.setInitParameter("org.eclipse.jetty.servlet.Default.useFileMappedBuffer", "false");	// webApp.setInitParams(Collections.singletonMap("org.mortbay.jetty.servlet.Default.useFileMappedBuffer", "false"));
-		persistSession(webApp);
-		
-		server.setHandler(webApp);
-		// changeClassLoader(webApp);
-		
-		// configureScanner
-//		if (scanIntervalSeconds > 0) {
-//			Scanner scanner = new Scanner(PathKit.getRootClassPath(), scanIntervalSeconds) {
-//				public void onChange() {
-//					try {
-//						System.err.println("\nLoading changes ......");
-//						webApp.stop();
-//						JFinalClassLoader loader = new JFinalClassLoader(webApp, getClassPath());
-//						webApp.setClassLoader(loader);
-//						webApp.start();
-//						System.err.println("Loading complete.");
-//					} catch (Exception e) {
-//						System.err.println("Error reconfiguring/restarting webapp after change in watched files");
-//						LogKit.error(e.getMessage(), e);
-//					}
-//				}
-//			};
-//			System.out.println("Starting scanner at interval of " + scanIntervalSeconds + " seconds.");
-//			scanner.start();
-//		}
-		
-		try {
-			System.out.println("Starting web server on port: " + port);
-			server.start();
-			System.out.println("Starting Complete. Welcome To The JFinal World :)");
-			server.join();
-		} catch (Exception e) {
-			LogKit.error(e.getMessage(), e);
-			System.exit(100);
-		}
-		return;
-	}
-	
-//	private void changeClassLoader(WebAppContext webApp) {
-//		try {
-//			String classPath = getClassPath();
-//			JFinalClassLoader jfcl = new JFinalClassLoader(webApp, classPath);
-//			// jfcl.addClassPath(classPath);
-//			webApp.setClassLoader(jfcl);
-//		} catch (IOException e) {
-//			LogKit.error(e.getMessage(), e);
-//		}
-//	}
-	
-//	private String getClassPath() {
-//		return System.getProperty("java.class.path");
-//	}
-	
-	private void deleteSessionData() {
-		try {
-			FileKit.delete(new File(getStoreDir()));
-		}
-		catch (Exception e) {
-			LogKit.logNothing(e);
-		}
-	}
-	
-	private String getStoreDir() {
-		String storeDir = PathKit.getWebRootPath() + "/../../session_data" + context;
-		if ("\\".equals(File.separator)) {
-			storeDir = storeDir.replaceAll("/", "\\\\");
-		}
-		return storeDir;
-	}
-	
-	private void persistSession(WebAppContext webApp) {
-		String storeDir = getStoreDir();
-		
-		SessionManager sm = webApp.getSessionHandler().getSessionManager();
-		if (sm instanceof HashSessionManager) {
-			((HashSessionManager)sm).setStoreDirectory(new File(storeDir));
-			return ;
-		}
-		
-		HashSessionManager hsm = new HashSessionManager();
-		hsm.setStoreDirectory(new File(storeDir));
-		SessionHandler sh = new SessionHandler();
-		sh.setSessionManager(hsm);
-		webApp.setSessionHandler(sh);
-	}
-	
-	private static boolean available(int port) {
-		if (port <= 0) {
-			throw new IllegalArgumentException("Invalid start port: " + port);
-		}
-		
-		ServerSocket ss = null;
-		DatagramSocket ds = null;
-		try {
-			ss = new ServerSocket(port);
-			ss.setReuseAddress(true);
-			ds = new DatagramSocket(port);
-			ds.setReuseAddress(true);
-			return true;
-		} catch (IOException e) {
-			LogKit.logNothing(e);
-		} finally {
-			if (ds != null) {
-				ds.close();
-			}
-			
-			if (ss != null) {
-				try {
-					ss.close();
-				} catch (IOException e) {
-					// should not be thrown, just detect port available.
-					LogKit.logNothing(e);
-				}
-			}
-		}
-		return false;
-	}
-}
-
-
-
-
-
-

+ 1 - 1
src/main/java/com/jfinal/server/Run_Configurations.txt

@@ -5,7 +5,7 @@ Run Configurations... / Debug Configurations...
     Main class(required) ---> com.jfinal.core.JFinal
 
 2: Argument
-    Program arguments(optional) ---> WebRoot 80 / 5
+    Program arguments(optional) ---> src/main/webapp 80 / 5
     VM arguments(optional) ---> -XX:PermSize=64M -XX:MaxPermSize=256M
 
 

+ 0 - 142
src/main/java/com/jfinal/server/Scanner.java

@@ -1,142 +0,0 @@
-/**
- * Copyright (c) 2011-2019, James Zhan 詹波 (jfinal@126.com).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.jfinal.server;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Timer;
-import java.util.TimerTask;
-import com.jfinal.kit.LogKit;
-import com.jfinal.kit.StrKit;
-
-/**
- * Scanner.
- */
-public abstract class Scanner {
-	
-	private Timer timer;
-	private TimerTask task;
-	private File rootDir;
-	private int interval;
-	private boolean running = false;
-	
-	private Map<String,TimeSize> preScan = new HashMap<String,TimeSize> ();
-	private Map<String,TimeSize> curScan = new HashMap<String,TimeSize> ();
-	
-	public Scanner(String rootDir, int interval) {
-		if (StrKit.isBlank(rootDir))
-			throw new IllegalArgumentException("The parameter rootDir can not be blank.");
-		this.rootDir = new File(rootDir);
-		if (!this.rootDir.isDirectory())
-			throw new IllegalArgumentException("The directory " + rootDir + " is not exists.");
-		if (interval <= 0)
-			throw new IllegalArgumentException("The parameter interval must more than zero.");
-		this.interval = interval;
-	}
-	
-	public abstract void onChange();
-	
-	private void working() {
-		scan(rootDir);
-		compare();
-		
-		// 优化性能
-		// preScan.clear();
-		// preScan.putAll(curScan);
-		// curScan.clear();
-		Map<String,TimeSize> temp = preScan;
-		preScan = curScan;
-		curScan = temp;
-		curScan.clear();
-	}
-	
-	private void scan(File file) {
-		if (file == null || !file.exists())
-			return ;
-		
-		if (file.isFile()) {
-			try {
-				curScan.put(file.getCanonicalPath(), new TimeSize(file.lastModified(),file.length()));
-			} catch (IOException e) {
-				LogKit.error(e.getMessage(), e);
-			}
-		}
-		else if (file.isDirectory()) {
-			File[] fs = file.listFiles();
-			if (fs != null)
-				for (File f : fs)
-					scan(f);
-		}
-	}
-	
-	private void compare() {
-		if (preScan.size() == 0) {
-			return;
-		}
-		
-		if (!preScan.equals(curScan)) {
-			onChange();
-		}
-	}
-	
-	public void start() {
-		if (!running) {
-			timer = new Timer("JFinal-Scanner", true);
-			task = new TimerTask() {public void run() {working();}};
-			timer.schedule(task, 1010L * interval, 1010L * interval);
-			running = true;
-		}
-	}
-	
-	public void stop() {
-		if (running) {
-			timer.cancel();
-			task.cancel();
-			running = false;
-		}
-	}
-}
-
-class TimeSize {
-	
-	final long time;
-	final long size;
-	
-	public TimeSize(long time, long size) {
-		this.time = time;
-		this.size = size;
-	}
-	
-	public int hashCode() {
-		return (int)(time ^ size);
-	}
-	
-	public boolean equals(Object o) {
-		if (o instanceof TimeSize) {
-			TimeSize ts = (TimeSize)o;
-			return ts.time == this.time && ts.size == this.size;
-		}
-		return false;
-	}
-	
-	public String toString() {
-		return "[t=" + time + ", s=" + size + "]";
-	}
-}
-

+ 0 - 96
src/main/java/com/jfinal/server/ServerFactory.java

@@ -1,96 +0,0 @@
-/**
- * Copyright (c) 2011-2019, James Zhan 詹波 (jfinal@126.com).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.jfinal.server;
-
-import java.io.File;
-import com.jfinal.kit.PathKit;
-
-/**
- * ServerFactory
- */
-public class ServerFactory {
-	
-	private static final int DEFAULT_PORT = 80;
-	private static final int DEFAULT_SCANINTERVALSECONDS = 5;
-	
-	private ServerFactory() {
-		
-	}
-	
-	/**
-	 * Return web server.
-	 * <p>
-	 * important: if scanIntervalSeconds < 1 then you will turn off the hot swap
-	 * @param webAppDir the directory of the project web root
-	 * @param port the port
-	 * @param context the context
-	 * @param scanIntervalSeconds the scan interval seconds
-	 */
-	public static IServer getServer(String webAppDir, int port, String context, int scanIntervalSeconds) {
-		return new JettyServer(webAppDir, port, context, scanIntervalSeconds);
-	}
-	
-	public static IServer getServer(String webAppDir, int port, String context) {
-		return getServer(webAppDir, port, context, DEFAULT_SCANINTERVALSECONDS);
-	}
-	
-	public static IServer getServer(int port, String context, int scanIntervalSeconds) {
-		return getServer(detectWebAppDir(), port, context, scanIntervalSeconds);
-	}
-	
-	public static IServer getServer(int port, String context) {
-		return getServer(detectWebAppDir(), port, context, DEFAULT_SCANINTERVALSECONDS);
-	}
-	
-	public static IServer getServer(int port) {
-		return getServer(detectWebAppDir(), port, "/", DEFAULT_SCANINTERVALSECONDS);
-	}
-	
-	public static IServer getServer() {
-		return getServer(detectWebAppDir(), DEFAULT_PORT, "/", DEFAULT_SCANINTERVALSECONDS);
-	}
-	
-	private static String detectWebAppDir() {
-		String rootClassPath = PathKit.getRootClassPath();
-		String[] temp = null;
-		if (rootClassPath.indexOf("\\WEB-INF\\") != -1)
-			temp = rootClassPath.split("\\\\");
-		else if (rootClassPath.indexOf("/WEB-INF/") != -1)
-			temp = rootClassPath.split("/");
-		else
-			throw new RuntimeException("WEB-INF directory not found.");
-		return temp[temp.length - 3];
-	}
-	
-	@SuppressWarnings("unused")
-	@Deprecated
-	private static String detectWebAppDir_old() {
-		String rootClassPath = PathKit.getRootClassPath();
-		String[] temp = null;
-		try {
-			temp = rootClassPath.split(File.separator);
-		}
-		catch (Exception e) {
-			temp = rootClassPath.split("\\\\");
-		}
-		return temp[temp.length - 3];
-	}
-}
-
-
-
-