Author: hlship
Date: Tue Nov 1 23:11:10 2011
New Revision: 1196370
URL: http://svn.apache.org/viewvc?rev=1196370&view=rev
Log:
TAP5-1739: Recode component class reload tests around ASM instead of Javassist
Added:
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ClassCreationHelper.java
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentInstantiatorSourceImplTest.java
Added:
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ClassCreationHelper.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ClassCreationHelper.java?rev=1196370&view=auto
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ClassCreationHelper.java
(added)
+++
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ClassCreationHelper.java
Tue Nov 1 23:11:10 2011
@@ -0,0 +1,135 @@
+// Copyright 2011 The Apache Software Foundation
+//
+// 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 org.apache.tapestry5.internal.services;
+
+import org.apache.tapestry5.internal.plastic.PlasticInternalUtils;
+import org.apache.tapestry5.internal.plastic.asm.ClassWriter;
+import org.apache.tapestry5.internal.plastic.asm.MethodVisitor;
+import org.apache.tapestry5.ioc.Registry;
+import org.apache.tapestry5.ioc.RegistryBuilder;
+import org.apache.tapestry5.services.TapestryModule;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.net.URLConnection;
+import java.util.UUID;
+
+import static org.apache.tapestry5.internal.plastic.asm.Opcodes.*;
+
+public class ClassCreationHelper
+{
+ private static final ClassLoader contextLoader =
Thread.currentThread().getContextClassLoader();
+
+ private String tempDir;
+
+ private URLClassLoader extraLoader;
+
+ public final Registry registry;
+
+ public ClassCreationHelper(Class... extraModules) throws Exception
+ {
+ tempDir = String.format("%s/tapestry-test-classpath/%s",
+ System.getProperty("java.io.tmpdir"),
+ UUID.randomUUID().toString());
+
+ File extraClasspath = new File(tempDir);
+
+ extraClasspath.mkdirs();
+
+ URL url = extraClasspath.toURL();
+
+ URLClassLoader extraLoader = new URLClassLoader(new URL[]
+ {url}, contextLoader);
+
+ RegistryBuilder builder = new RegistryBuilder(extraLoader);
+
+ builder.add(TapestryModule.class);
+ builder.add(extraModules);
+
+ registry = builder.build();
+ }
+
+ public void writeFile(ClassWriter writer, String className) throws
Exception
+ {
+ File classFile = toFile(className);
+
+ classFile.getParentFile().mkdirs();
+
+ OutputStream os = new BufferedOutputStream(new
FileOutputStream(classFile));
+
+ os.write(writer.toByteArray());
+
+ os.close();
+ }
+
+ public ClassWriter createWriter(String className, String superClassName,
String... interfaceNames)
+ {
+ String[] interfaceInternalNames = new String[interfaceNames.length];
+ for (int i = 0; i < interfaceNames.length; i++)
+ {
+ interfaceInternalNames[i] =
PlasticInternalUtils.toInternalName(interfaceNames[i]);
+ }
+
+ ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES +
ClassWriter.COMPUTE_MAXS);
+
+ cw.visit(V1_5, ACC_PUBLIC,
PlasticInternalUtils.toInternalName(className), null,
+ PlasticInternalUtils.toInternalName(superClassName),
interfaceInternalNames);
+
+ return cw;
+ }
+
+ public void implementPublicConstructor(ClassWriter cw, String
superClassName)
+ {
+
+ MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null,
null);
+ mv.visitCode();
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitMethodInsn(INVOKESPECIAL,
PlasticInternalUtils.toInternalName(superClassName), "<init>", "()V");
+ mv.visitInsn(RETURN);
+ mv.visitEnd();
+ }
+
+
+ public long readDTM(String className) throws Exception
+ {
+ URL url = toFile(className).toURL();
+
+ return readDTM(url);
+ }
+
+ private File toFile(String className)
+ {
+ String path = String.format("%s/%s.class",
+ tempDir,
+ PlasticInternalUtils.toInternalName(className));
+
+ return new File(path);
+ }
+
+ private long readDTM(URL url) throws Exception
+ {
+ URLConnection connection = url.openConnection();
+
+ connection.connect();
+
+ return connection.getLastModified();
+ }
+
+
+}
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentInstantiatorSourceImplTest.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentInstantiatorSourceImplTest.java?rev=1196370&r1=1196369&r2=1196370&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentInstantiatorSourceImplTest.java
(original)
+++
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentInstantiatorSourceImplTest.java
Tue Nov 1 23:11:10 2011
@@ -14,52 +14,36 @@
package org.apache.tapestry5.internal.services;
-import java.io.File;
-import java.io.IOException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.net.URLConnection;
-import java.util.UUID;
-
-import javassist.CannotCompileException;
-import javassist.ClassPool;
-import javassist.CtClass;
-import javassist.CtMethod;
-import javassist.CtNewMethod;
-import javassist.LoaderClassPath;
-import javassist.NotFoundException;
-
import org.apache.tapestry5.internal.InternalComponentResources;
+import org.apache.tapestry5.internal.plastic.asm.ClassWriter;
+import org.apache.tapestry5.internal.plastic.asm.MethodVisitor;
import org.apache.tapestry5.internal.test.InternalBaseTestCase;
import org.apache.tapestry5.internal.transform.pages.BasicComponent;
import org.apache.tapestry5.ioc.Registry;
-import org.apache.tapestry5.ioc.RegistryBuilder;
import org.apache.tapestry5.runtime.Component;
-import org.apache.tapestry5.services.TapestryModule;
import org.apache.tapestry5.services.UpdateListenerHub;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
+import static org.apache.tapestry5.internal.plastic.asm.Opcodes.ACC_PUBLIC;
+import static org.apache.tapestry5.internal.plastic.asm.Opcodes.ARETURN;
+
/**
* Tests for {@link
org.apache.tapestry5.internal.services.ComponentInstantiatorSourceImpl}.
Several of these tests are
* more of the form of integration tests that instantiate the Tapestry IoC
Registry.
*/
public class ComponentInstantiatorSourceImplTest extends InternalBaseTestCase
{
- private static final ClassLoader contextLoader =
Thread.currentThread().getContextClassLoader();
+ private static final String BASIC_COMPONENT_CLASSNAME =
BasicComponent.class.getName();
private static final String SYNTH_COMPONENT_CLASSNAME =
"org.apache.tapestry5.internal.transform.pages.SynthComponent";
- private File extraClasspath;
-
private ComponentInstantiatorSource source;
- private Registry registry;
-
- private ClassLoader extraLoader;
+ private ClassCreationHelper helper;
- private String tempDir;
+ private Registry registry;
/**
* This allows tests the exists() method.
@@ -83,19 +67,16 @@ public class ComponentInstantiatorSource
assertEquals(named.getName(), "Original");
- String path = tempDir + "/" + SYNTH_COMPONENT_CLASSNAME.replace('.',
'/') + ".class";
- URL url = new File(path).toURL();
-
- long dtm = readDTM(url);
+ long dtm = helper.readDTM(SYNTH_COMPONENT_CLASSNAME);
while (true)
{
- if (readDTM(url) != dtm)
+ createSynthComponentClass("Updated");
+
+ if (helper.readDTM(SYNTH_COMPONENT_CLASSNAME) != dtm)
break;
// Keep re-writing the file until we see the DTM change.
-
- createSynthComponentClass("Updated");
}
// Detect the change and clear out the internal caches
@@ -111,34 +92,22 @@ public class ComponentInstantiatorSource
assertEquals(named.getName(), "Updated");
}
- private long readDTM(URL url) throws Exception
- {
- URLConnection connection = url.openConnection();
- connection.connect();
-
- return connection.getLastModified();
- }
-
- private void createSynthComponentClass(String name) throws
CannotCompileException, NotFoundException, IOException
+ private void createSynthComponentClass(String name) throws Exception
{
- ClassPool pool = new ClassPool();
- // Inside Maven Surefire, the system classpath is not sufficient to
find all
- // the necessary files.
- pool.appendClassPath(new LoaderClassPath(extraLoader));
+ ClassWriter cw = helper.createWriter(SYNTH_COMPONENT_CLASSNAME,
BASIC_COMPONENT_CLASSNAME, Named.class.getName());
- CtClass ctClass = pool.makeClass(SYNTH_COMPONENT_CLASSNAME);
+ helper.implementPublicConstructor(cw, BASIC_COMPONENT_CLASSNAME);
- ctClass.setSuperclass(pool.get(BasicComponent.class.getName()));
+ MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "getName",
"()Ljava/lang/String;", null, null);
+ mv.visitCode();
+ mv.visitLdcInsn(name);
+ mv.visitInsn(ARETURN);
+ mv.visitEnd();
- // Implement method getName()
+ cw.visitEnd();
- CtMethod method = CtNewMethod.make("public String getName() { return
\"" + name + "\"; }", ctClass);
- ctClass.addMethod(method);
-
- ctClass.addInterface(pool.get(Named.class.getName()));
-
- ctClass.writeFile(extraClasspath.getAbsolutePath());
+ helper.writeFile(cw, SYNTH_COMPONENT_CLASSNAME);
}
private Component createComponent(String classname)
@@ -159,25 +128,9 @@ public class ComponentInstantiatorSource
@BeforeClass
public void setup_tests() throws Exception
{
- String tempdir = System.getProperty("java.io.tmpdir");
- String uid = UUID.randomUUID().toString();
-
- tempDir = tempdir + "/tapestry-test-classpath/" + uid;
- extraClasspath = new File(tempDir);
-
- System.out.println("Creating dir: " + extraClasspath);
-
- extraClasspath.mkdirs();
-
- URL url = extraClasspath.toURL();
-
- extraLoader = new URLClassLoader(new URL[]
- { url }, contextLoader);
- RegistryBuilder builder = new RegistryBuilder(extraLoader);
-
- builder.add(TapestryModule.class, ForceDevelopmentModeModule.class,
AddTransformPagesToCISModule.class);
+ helper = new ClassCreationHelper(ForceDevelopmentModeModule.class,
AddTransformPagesToCISModule.class);
- registry = builder.build();
+ registry = helper.registry;
source = registry.getService(ComponentInstantiatorSource.class);
}