Skip to content

Commit

Permalink
#38 Completed the app hot reload/restart process.
Browse files Browse the repository at this point in the history
  • Loading branch information
nmihajlovski committed Feb 21, 2016
1 parent c8157ff commit 1b2aa34
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 94 deletions.
20 changes: 12 additions & 8 deletions rapidoid-commons/src/main/java/org/rapidoid/cls/Cls.java
Expand Up @@ -20,10 +20,7 @@
* #L% * #L%
*/ */


import javassist.ClassPool; import javassist.*;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.NotFoundException;
import javassist.bytecode.CodeAttribute; import javassist.bytecode.CodeAttribute;
import javassist.bytecode.LocalVariableAttribute; import javassist.bytecode.LocalVariableAttribute;
import javassist.bytecode.MethodInfo; import javassist.bytecode.MethodInfo;
Expand Down Expand Up @@ -1028,8 +1025,12 @@ public static Method getLambdaMethod(Serializable lambda) {


String className = serializedLambda.getImplClass().replaceAll("/", "."); String className = serializedLambda.getImplClass().replaceAll("/", ".");


Class<?> cls = getClassIfExists(className); Class<?> cls;
U.must(cls != null, "Cannot find or load the lambda class: %s", cls); try {
cls = Class.forName(className, true, lambda.getClass().getClassLoader());
} catch (ClassNotFoundException e) {
throw U.rte("Cannot find or load the lambda class: %s", className);
}


String lambdaMethodName = serializedLambda.getImplMethodName(); String lambdaMethodName = serializedLambda.getImplMethodName();


Expand All @@ -1039,7 +1040,7 @@ public static Method getLambdaMethod(Serializable lambda) {
} }
} }


throw U.rte("Cannot find the lambda method!"); throw U.rte("Cannot find the lambda method: %s#%s", cls.getName(), lambdaMethodName);
} }


public static String[] getMethodParameterNames(Method method) { public static String[] getMethodParameterNames(Method method) {
Expand All @@ -1058,14 +1059,17 @@ public static String[] getMethodParameterNames(Method method) {
if (defaultNames) { if (defaultNames) {
CtMethod cm; CtMethod cm;
try { try {
ClassPool cp = ClassPool.getDefault(); ClassPool cp = new ClassPool();
cp.insertClassPath(new ClassClassPath(method.getDeclaringClass()));
CtClass cc = cp.get(method.getDeclaringClass().getName()); CtClass cc = cp.get(method.getDeclaringClass().getName());


CtClass[] params = new CtClass[method.getParameterCount()]; CtClass[] params = new CtClass[method.getParameterCount()];
for (int i = 0; i < params.length; i++) { for (int i = 0; i < params.length; i++) {
params[i] = cp.get(method.getParameterTypes()[i].getName()); params[i] = cp.get(method.getParameterTypes()[i].getName());
} }

cm = cc.getDeclaredMethod(method.getName(), params); cm = cc.getDeclaredMethod(method.getName(), params);

} catch (NotFoundException e) { } catch (NotFoundException e) {
throw U.rte("Cannot find the target method!", e); throw U.rte("Cannot find the target method!", e);
} }
Expand Down
7 changes: 7 additions & 0 deletions rapidoid-commons/src/main/java/org/rapidoid/config/Conf.java
Expand Up @@ -36,6 +36,8 @@ public class Conf {


private static final Config ROOT = new Config(); private static final Config ROOT = new Config();


private static volatile String[] args;

static { static {
RapidoidInitializer.initialize(); RapidoidInitializer.initialize();
} }
Expand All @@ -49,6 +51,7 @@ public Map<String, Object> parse(byte[] bytes) {
}; };


public static synchronized void args(String... args) { public static synchronized void args(String... args) {
Conf.args = args;
ConfigHelp.processHelp(args); ConfigHelp.processHelp(args);


if (args != null) { if (args != null) {
Expand All @@ -64,6 +67,10 @@ public static synchronized void args(String... args) {
} }
} }


public static String[] getArgs() {
return args;
}

public static void remove(String name) { public static void remove(String name) {
ROOT.remove(name); ROOT.remove(name);
} }
Expand Down
2 changes: 0 additions & 2 deletions rapidoid-commons/src/test/java/org/rapidoid/cls/ClsTest.java
Expand Up @@ -54,7 +54,6 @@ public void testWithManyParams() {
Method m2 = U.single(Cls.getMethodsNamed(Foo.class, "xyz")); Method m2 = U.single(Cls.getMethodsNamed(Foo.class, "xyz"));
String[] names2 = Cls.getMethodParameterNames(m2); String[] names2 = Cls.getMethodParameterNames(m2);
eq(names2, U.array("a", "b", "c", "d", "e", "f", "g", "hh", "ii", "j")); eq(names2, U.array("a", "b", "c", "d", "e", "f", "g", "hh", "ii", "j"));

} }


} }
Expand Down Expand Up @@ -85,5 +84,4 @@ public String xyz(@Param("a") byte a, @Param("b") short b, @Param("c") char c, @
return U.join(":", a, b, c, d, e, f, g, hh, ii, j); return U.join(":", a, b, c, d, e, f, g, hh, ii, j);
} }



} }
Expand Up @@ -24,16 +24,14 @@
import org.rapidoid.web.On; import org.rapidoid.web.On;


/** /**
* Demo for class reloading. E.g. try changing the Abc class... * Demo for class reloading. Try changing the classes
*/ */
public class ReloadDemo { public class ReloadDemo {


public static void main(String[] args) { public static void main(String[] args) {
On.bootstrap(); On.bootstrap();


On.changes().restart(); On.get("/xy").json((Req req, String x, Integer y) -> x + "::" + y);

On.get("/aa").json((Req req, String x) -> x + ":" + req);
} }


} }
@@ -0,0 +1,28 @@
package org.rapidoid.web;

import org.rapidoid.annotation.Authors;
import org.rapidoid.annotation.Since;
import org.rapidoid.data.Range;
import org.rapidoid.data.Ranges;
import org.rapidoid.http.processor.AbstractHttpProcessor;
import org.rapidoid.http.processor.HttpProcessor;
import org.rapidoid.net.abstracts.Channel;

@Authors("Nikolche Mihajlovski")
@Since("5.1.0")
public class AppRestartProcessor extends AbstractHttpProcessor {

public AppRestartProcessor(Setup setup, HttpProcessor next) {
super(next);
}

@Override
public void request(Channel channel, boolean isGet, boolean isKeepAlive, Range body,
Range verb, Range uri, Range path, Range query, Range protocol, Ranges headers) {

Setup.restartIfDirty();

next.request(channel, isGet, isKeepAlive, body, verb, uri, path, query, protocol, headers);
}

}
66 changes: 30 additions & 36 deletions rapidoid-web/src/main/java/org/rapidoid/web/On.java
Expand Up @@ -48,137 +48,131 @@ public void run() {
}); });
} }


private static final Setup DEFAULT_SETUP = new Setup("http", "0.0.0.0", 8888, ServerSetupType.DEFAULT, IoC.defaultContext());

private static final Setup ADMIN_SETUP = new Setup("admin", "0.0.0.0", 8889, ServerSetupType.ADMIN, IoC.defaultContext());

private static final Setup DEV_SETUP = new Setup("dev", "127.0.0.1", 8887, ServerSetupType.DEV, IoC.defaultContext());

public static synchronized OnAction get(String path) { public static synchronized OnAction get(String path) {
return DEFAULT_SETUP.get(path); return Setup.DEFAULT.get(path);
} }


public static synchronized OnAction post(String path) { public static synchronized OnAction post(String path) {
return DEFAULT_SETUP.post(path); return Setup.DEFAULT.post(path);
} }


public static synchronized OnAction put(String path) { public static synchronized OnAction put(String path) {
return DEFAULT_SETUP.put(path); return Setup.DEFAULT.put(path);
} }


public static synchronized OnAction delete(String path) { public static synchronized OnAction delete(String path) {
return DEFAULT_SETUP.delete(path); return Setup.DEFAULT.delete(path);
} }


public static synchronized OnAction patch(String path) { public static synchronized OnAction patch(String path) {
return DEFAULT_SETUP.patch(path); return Setup.DEFAULT.patch(path);
} }


public static synchronized OnAction options(String path) { public static synchronized OnAction options(String path) {
return DEFAULT_SETUP.options(path); return Setup.DEFAULT.options(path);
} }


public static synchronized OnAction head(String path) { public static synchronized OnAction head(String path) {
return DEFAULT_SETUP.head(path); return Setup.DEFAULT.head(path);
} }


public static synchronized OnAction trace(String path) { public static synchronized OnAction trace(String path) {
return DEFAULT_SETUP.trace(path); return Setup.DEFAULT.trace(path);
} }


public static synchronized OnPage page(String path) { public static synchronized OnPage page(String path) {
return DEFAULT_SETUP.page(path); return Setup.DEFAULT.page(path);
} }


public static synchronized Setup error(ErrorHandler onError) { public static synchronized Setup error(ErrorHandler onError) {
return DEFAULT_SETUP.onError(onError); return Setup.DEFAULT.onError(onError);
} }


public static synchronized Setup req(ReqHandler handler) { public static synchronized Setup req(ReqHandler handler) {
return DEFAULT_SETUP.req(handler); return Setup.DEFAULT.req(handler);
} }


public static synchronized Setup req(ReqRespHandler handler) { public static synchronized Setup req(ReqRespHandler handler) {
return DEFAULT_SETUP.req(handler); return Setup.DEFAULT.req(handler);
} }


public static synchronized Setup req(FastHttpHandler handler) { public static synchronized Setup req(FastHttpHandler handler) {
return DEFAULT_SETUP.req(handler); return Setup.DEFAULT.req(handler);
} }


public static synchronized Setup beans(Object... controllers) { public static synchronized Setup beans(Object... controllers) {
return DEFAULT_SETUP.beans(controllers); return Setup.DEFAULT.beans(controllers);
} }


public static synchronized Setup port(int port) { public static synchronized Setup port(int port) {
return DEFAULT_SETUP.port(port); return Setup.DEFAULT.port(port);
} }


public static synchronized Setup address(String address) { public static synchronized Setup address(String address) {
return DEFAULT_SETUP.address(address); return Setup.DEFAULT.address(address);
} }


public static Setup path(String... path) { public static Setup path(String... path) {
return DEFAULT_SETUP.path(path); return Setup.DEFAULT.path(path);
} }


public static String[] path() { public static String[] path() {
return DEFAULT_SETUP.path(); return Setup.DEFAULT.path();
} }


public static synchronized Setup wrap(HttpWrapper... wrappers) { public static synchronized Setup wrap(HttpWrapper... wrappers) {
return DEFAULT_SETUP.wrap(wrappers); return Setup.DEFAULT.wrap(wrappers);
} }


public static synchronized Setup processor(HttpProcessor listener) { public static synchronized Setup processor(HttpProcessor listener) {
return DEFAULT_SETUP.processor(listener); return Setup.DEFAULT.processor(listener);
} }


public static synchronized Setup getDefaultSetup() { public static synchronized Setup getDefaultSetup() {
return DEFAULT_SETUP; return Setup.DEFAULT;
} }


public static Setup createSetup(String name) { public static Setup createSetup(String name) {
return new Setup(name, "0.0.0.0", 8888, ServerSetupType.CUSTOM, IoC.createContext()); return new Setup(name, "0.0.0.0", 8888, ServerSetupType.CUSTOM, IoC.createContext());
} }


public static synchronized Setup staticFilesLookIn(String... possibleLocations) { public static synchronized Setup staticFilesLookIn(String... possibleLocations) {
return DEFAULT_SETUP.staticFilesPath(possibleLocations); return Setup.DEFAULT.staticFilesPath(possibleLocations);
} }


public static synchronized Setup render(ViewRenderer renderer) { public static synchronized Setup render(ViewRenderer renderer) {
return DEFAULT_SETUP.render(renderer); return Setup.DEFAULT.render(renderer);
} }


public static Setup args(String... args) { public static Setup args(String... args) {
Conf.args(args); Conf.args(args);
return DEFAULT_SETUP; return Setup.DEFAULT;
} }


public static Setup bootstrap() { public static Setup bootstrap() {
return DEFAULT_SETUP.bootstrap(); return Setup.DEFAULT.bootstrap();
} }


@SafeVarargs @SafeVarargs
@SuppressWarnings({"varargs"}) @SuppressWarnings({"varargs"})
public static OnAnnotated annotated(Class<? extends Annotation>... annotated) { public static OnAnnotated annotated(Class<? extends Annotation>... annotated) {
return DEFAULT_SETUP.annotated(annotated); return Setup.DEFAULT.annotated(annotated);
} }


public static Setup admin() { public static Setup admin() {
return ADMIN_SETUP; return Setup.ADMIN;
} }


public static Setup dev() { public static Setup dev() {
return DEV_SETUP; return Setup.DEV;
} }


public static Setup deregister(String verb, String path) { public static Setup deregister(String verb, String path) {
return DEFAULT_SETUP.deregister(verb, path); return Setup.DEFAULT.deregister(verb, path);
} }


public static Setup deregister(Object... controllers) { public static Setup deregister(Object... controllers) {
return DEFAULT_SETUP.deregister(controllers); return Setup.DEFAULT.deregister(controllers);
} }


public static OnChanges changes() { public static OnChanges changes() {
Expand Down

0 comments on commit 1b2aa34

Please sign in to comment.