Skip to content

Commit

Permalink
Adapt the live mode to the new LiveClassLoader
Browse files Browse the repository at this point in the history
  • Loading branch information
vietj committed Oct 16, 2013
1 parent 62a3c8d commit cd14ad5
Show file tree
Hide file tree
Showing 10 changed files with 67 additions and 41 deletions.
7 changes: 6 additions & 1 deletion core/src/main/java/juzu/impl/common/LiveClassLoader.java
Expand Up @@ -37,9 +37,14 @@ public class LiveClassLoader extends URLClassLoader {
/** . */
private final ClassLoader parent;

public LiveClassLoader(URL[] urls, ClassLoader parent) {
public LiveClassLoader(URL[] urls, ClassLoader parent) throws NullPointerException {
super(urls, parent);

//
if (parent == null) {
throw new NullPointerException("No null parent classloader accpeted");
}

//
this.parent = parent;
}
Expand Down
6 changes: 2 additions & 4 deletions core/src/main/java/juzu/impl/compiler/Compiler.java
Expand Up @@ -404,11 +404,9 @@ public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
};

//
List<String> options = null;
List<String> options = new ArrayList<String>();
options.add("-g");
for (String optionName : config.getProcessorOptionNames()) {
if (options == null) {
options = new ArrayList<String>();
}
options.add("-A" + optionName + "=" + config.getProcessorOptionValue(optionName));
}

Expand Down
Expand Up @@ -19,7 +19,6 @@
import juzu.Scope;
import juzu.impl.plugin.application.Application;
import juzu.impl.common.JSON;
import juzu.impl.common.Name;
import juzu.impl.inject.spi.InjectionContext;
import juzu.impl.common.Tools;
import juzu.impl.inject.spi.cdi.provided.ProvidedCDIInjector;
Expand Down Expand Up @@ -80,9 +79,7 @@ void beforeBeanDiscovery(@Observes BeforeBeanDiscovery event, final BeanManager
throw new RuntimeException("Was expecting application size to be 1 instead of " + applications);
}
String packageFQN = applications.names().iterator().next();
Name applicationFQN = Name.parse(packageFQN).append("Application");
Class<?> clazz = cl.loadClass(applicationFQN.toString());
ApplicationDescriptor descriptor = ApplicationDescriptor.create(clazz);
ApplicationDescriptor descriptor = ApplicationDescriptor.create(cl, packageFQN);
// For now we don't resolve anything...
ResourceResolver resourceResolver = new ResourceResolver() {
public URL resolve(String uri) {
Expand Down
10 changes: 7 additions & 3 deletions core/src/main/java/juzu/impl/plugin/application/Application.java
Expand Up @@ -58,7 +58,11 @@ public class Application {
/** . */
private Map<String, ApplicationPlugin> plugins;

/** . */
private final ClassLoader classLoader;

public Application(Injector injector, ApplicationDescriptor descriptor, ResourceResolver resourceResolver) {
this.classLoader = descriptor.getApplicationLoader();
this.injectionContext = null;
this.descriptor = descriptor;
this.injector = injector;
Expand All @@ -71,7 +75,7 @@ public void start() throws Exception {
final ResourceResolver applicationResolver = new ResourceResolver() {
public URL resolve(String uri) {
if (uri.startsWith("/")) {
return descriptor.getApplicationLoader().getResource(uri.substring(1));
return classLoader.getResource(uri.substring(1));
} else {
return null;
}
Expand Down Expand Up @@ -106,7 +110,7 @@ public JSON getConfig() {
return entry.getValue();
}
public ClassLoader getClassLoader() {
return descriptor.getApplicationLoader();
return classLoader;
}
public ResourceResolver getServerResolver() {
return resourceResolver;
Expand Down Expand Up @@ -174,7 +178,7 @@ public boolean accept(Class<?> elt) {
return false;
} else {
try {
Class<?> packageClass = descriptor.getApplicationLoader().loadClass(currentPkg + ".package-info");
Class<?> packageClass = classLoader.loadClass(currentPkg + ".package-info");
juzu.Application ann = packageClass.getAnnotation(juzu.Application.class);
if (ann != null) {
blackList.add(currentPkg);
Expand Down
Expand Up @@ -29,14 +29,31 @@
public class ApplicationDescriptor extends PluginDescriptor {

/**
* Encapsulate application descriptor loading from an application class.
* Encapsulate application descriptor loading from an application name.
*
* @param loader the application loader
* @param applicationName the application name
* @return the descriptor
* @throws Exception any exception that would prevent the exception to be loaded
*/
public static ApplicationDescriptor create(ClassLoader loader, String applicationName) throws Exception {
if (loader == null) {
throw new NullPointerException("No null loader accepted");
}
// Application class
Class<?> applicationClass = loader.loadClass(applicationName + ".Application");
return new ApplicationDescriptor(loader, applicationClass);
}

/**
* Encapsulate application descriptor loading from an application name.
*
* @param applicationClass the application class
* @return the descriptor
* @throws Exception any exception that would prevent the exception to be loaded
*/
public static ApplicationDescriptor create(Class<?> applicationClass) throws Exception {
return new ApplicationDescriptor(applicationClass);
return new ApplicationDescriptor(applicationClass.getClassLoader(), applicationClass);
}

/** . */
Expand All @@ -54,12 +71,18 @@ public static ApplicationDescriptor create(Class<?> applicationClass) throws Exc
/** . */
private final JSON config;

public ApplicationDescriptor(Class<?> applicationClass) throws Exception {
/** . */
private final ClassLoader loader;

private ApplicationDescriptor(ClassLoader loader, Class<?> applicationClass) throws Exception {


// Load config
JSON config;
InputStream in = null;
try {
in = applicationClass.getResourceAsStream("config.json");
String configPath = applicationClass.getPackage().getName().replace('.', '/') + "/config.json";
in = loader.getResourceAsStream(configPath);
String s = Tools.read(in);
config = (JSON)JSON.parse(s);
}
Expand All @@ -75,9 +98,7 @@ public ApplicationDescriptor(Class<?> applicationClass) throws Exception {
this.name = applicationClass.getSimpleName();
this.packageName = applicationClass.getPackage().getName();
this.packageClass = Tools.getPackageClass(applicationClass.getClassLoader(), applicationClass.getPackage().getName());


//
this.loader = loader;
this.config = config;
}

Expand All @@ -99,7 +120,7 @@ public Class<?> getApplicationClass() {
}

public ClassLoader getApplicationLoader() {
return applicationClass.getClassLoader();
return loader;
}

public String getPackageName() {
Expand Down
Expand Up @@ -260,6 +260,9 @@ private void emitController(ProcessingContext env, ControllerMetaModel controlle
writer.append("@Generated(value={})\n");
writer.append("public class ").append(fqn.getIdentifier()).append("_ {\n");

// Class literal
writer.append("private static final Class<").append(fqn).append("> TYPE = ").append(fqn).append(".class;\n");

//
int index = 0;
for (MethodMetaModel method : methods) {
Expand All @@ -281,8 +284,8 @@ private void emitController(ProcessingContext env, ControllerMetaModel controlle
writer.append("null,");
}
writer.append(PHASE).append(".").append(method.getPhase().name()).append(",");
writer.append(fqn).append(".class").append(",");
writer.append(TOOLS).append(".safeGetMethod(").append(fqn).append(".class,\"").append(method.getName()).append("\"");
writer.append("TYPE,");
writer.append(TOOLS).append(".safeGetMethod(TYPE,\"").append(method.getName()).append("\"");
for (ParameterMetaModel parameter : method.getParameters()) {
writer.append(",").append(parameter.typeLiteral).append(".class");
}
Expand Down Expand Up @@ -363,7 +366,7 @@ private void emitController(ProcessingContext env, ControllerMetaModel controlle

//
writer.append("public static final ").append(CONTROLLER_DESCRIPTOR).append(" DESCRIPTOR = new ").append(CONTROLLER_DESCRIPTOR).append("(");
writer.append(fqn.getIdentifier()).append(".class,Arrays.<").append(METHOD_DESCRIPTOR).append("<?>>asList(");
writer.append("TYPE,Arrays.<").append(METHOD_DESCRIPTOR).append("<?>>asList(");
for (int j = 0;j < methods.size();j++) {
if (j > 0) {
writer.append(',');
Expand Down
8 changes: 1 addition & 7 deletions core/src/main/java/juzu/impl/runtime/ApplicationRuntime.java
Expand Up @@ -24,7 +24,6 @@
import juzu.impl.inject.spi.BeanLifeCycle;
import juzu.impl.inject.spi.InjectionContext;
import juzu.impl.inject.spi.Injector;
import juzu.impl.inject.spi.spring.SpringInjector;
import juzu.impl.common.Logger;
import juzu.impl.plugin.application.Application;
import juzu.impl.plugin.application.descriptor.ApplicationDescriptor;
Expand All @@ -33,7 +32,6 @@

import java.io.Closeable;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;

/**
* The application life cycle.
Expand Down Expand Up @@ -137,11 +135,7 @@ protected final void start() throws Exception {
ReadFileSystem<?> classes = moduleLifeCycle.getClasses();

//
Name fqn = name.append("Application");

//
Class<?> clazz = moduleLifeCycle.getClassLoader().loadClass(fqn.toString());
ApplicationDescriptor descriptor = ApplicationDescriptor.create(clazz);
ApplicationDescriptor descriptor = ApplicationDescriptor.create(moduleLifeCycle.getClassLoader(), name.toString());

//
Injector injector = injectorProvider.get();
Expand Down
4 changes: 2 additions & 2 deletions core/src/main/java/juzu/impl/runtime/ModuleRuntime.java
Expand Up @@ -16,6 +16,7 @@

package juzu.impl.runtime;

import juzu.impl.common.LiveClassLoader;
import juzu.impl.common.ParentJarClassLoader;
import juzu.impl.common.Logger;
import juzu.impl.compiler.*;
Expand All @@ -30,7 +31,6 @@

import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;

/**
* The module life cycle.
Expand Down Expand Up @@ -158,7 +158,7 @@ public boolean acceptFile(S file, String name) throws IOException {
}, classOutput);

//
this.classLoader = new URLClassLoader(new URL[]{classOutput.getURL()}, classPathLoader);
this.classLoader = new LiveClassLoader(new URL[]{classOutput.getURL()}, baseClassLoader);
this.classes = classOutput;
this.snapshot = next;
this.failed = false;
Expand Down
Expand Up @@ -42,17 +42,15 @@ public abstract class AbstractRunModeLiveTestCase extends AbstractWebTestCase {

@Test
public void testRender() throws Exception {

//
driver.get(getURL().toString());
WebElement elt = driver.findElement(By.id("trigger"));
URL url = new URL(elt.getAttribute("href"));

//
driver.get(url.toString());
assertEquals("ok", driver.findElement(By.tagName("body")).getText());
assertTrue(SAME_CL_1);
assertTrue(SAME_CL_2);

// Now we should get an application error
assertFalse(SAME_CL_1);
assertFalse(SAME_CL_2);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
assertEquals(getErrorStatus(), conn.getResponseCode());
driver.get(url.toString());
Expand All @@ -61,14 +59,16 @@ public void testRender() throws Exception {
// Make a change
JavaFile pkgFile = getCompiler().assertSource("bridge", "runmode", "live", "A.java");
pkgFile.assertSave(pkgFile.assertContent().replace("\"ok\"", "\"OK\""));

//
driver.get(applicationURL().toString());
elt = driver.findElement(By.id("trigger"));
elt.click();
assertEquals("OK", driver.findElement(By.tagName("body")).getText());
assertTrue(SAME_CL_1);
assertTrue(SAME_CL_2);
assertFalse(SAME_CL_2);





// Now make fail with compilation error
pkgFile.assertSave(pkgFile.assertContent().replace("public", "_public_"));
Expand Down
4 changes: 4 additions & 0 deletions core/src/test/resources/bridge/runmode/live/A.java
Expand Up @@ -28,6 +28,10 @@ public class A {
/** . */
private static int count = 0;

public A() {
System.out.println("build");
}

@View
@Route("/foo")
public Response.Content index() {
Expand Down

0 comments on commit cd14ad5

Please sign in to comment.