-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
329 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
package t5750.javassist; | ||
|
||
import org.junit.Before; | ||
import org.junit.Test; | ||
|
||
import javassist.*; | ||
import t5750.javassist.loader.JavaClassLoader; | ||
import t5750.javassist.loader.SampleLoader; | ||
import t5750.javassist.service.Hello; | ||
import t5750.javassist.service.impl.MyTranslator; | ||
import t5750.javassist.util.JavassistUtil; | ||
|
||
public class ClassLoaderTest { | ||
private ClassPool pool; | ||
|
||
@Before | ||
public void setup() { | ||
pool = ClassPool.getDefault(); | ||
} | ||
|
||
/** | ||
* 3.1 The toClass method in CtClass | ||
*/ | ||
@Test | ||
public void toClassMethod() throws Exception { | ||
CtClass cc = pool.get(JavassistUtil.SERVICE + "Hello"); | ||
CtMethod m = cc.getDeclaredMethod("say"); | ||
m.insertBefore("{ System.out.println(\"Hello.say():\"); }"); | ||
Class c = cc.toClass(); | ||
Hello h = (Hello) c.newInstance(); | ||
h.say(); | ||
} | ||
|
||
/** | ||
* 3.2 Class loading in Java | ||
*/ | ||
@Test | ||
public void javaClassLoader() throws Exception { | ||
ClassLoader loader = this.getClass().getClassLoader(); | ||
Class clazz = loader.loadClass(JavassistUtil.SERVICE + "Hello"); | ||
Object obj = clazz.newInstance(); | ||
Hello b = (Hello) obj; // this always throws ClassCastException. | ||
} | ||
|
||
/** | ||
* 3.3 Using javassist.Loader | ||
*/ | ||
@Test | ||
public void javassistLoader() throws Throwable { | ||
Loader cl = new Loader(pool); | ||
CtClass ct = pool.get(JavassistUtil.DOMAIN + "Rectangle"); | ||
ct.setSuperclass(pool.get("java.awt.Point")); | ||
Class c = cl.loadClass(JavassistUtil.DOMAIN + "Rectangle"); | ||
Object rect = c.newInstance(); | ||
System.out.println(rect.toString()); | ||
// To run an application class MyApp with a MyTranslator object | ||
Translator t = new MyTranslator(); | ||
cl.addTranslator(pool, t); | ||
cl.run(JavassistUtil.SERVICE + "MyApp", JavassistUtil.ARGS); | ||
} | ||
|
||
/** | ||
* 3.4 Writing a class loader | ||
*/ | ||
@Test | ||
public void testSampleLoader() throws Throwable { | ||
SampleLoader.main(JavassistUtil.ARGS); | ||
} | ||
|
||
/** | ||
* 3.5 Modifying a system class | ||
*/ | ||
@Test | ||
public void modifySystemClass() throws Exception { | ||
CtClass cc = pool.get("java.lang.String"); | ||
CtField f = new CtField(CtClass.intType, "hiddenValue", cc); | ||
f.setModifiers(Modifier.PUBLIC); | ||
cc.addField(f); | ||
cc.writeFile("."); | ||
CtClass ccMyApp = pool.get(JavassistUtil.SERVICE + "MyApp"); | ||
CtMethod m = ccMyApp.getDeclaredMethod("main"); | ||
m.insertBefore("{ getHiddenValue(); }"); | ||
ccMyApp.writeFile(); | ||
// cd java-repositories/jdk8 | ||
// java -Xbootclasspath/p:. t5750.javassist.service.MyApp | ||
} | ||
|
||
/** | ||
* Dynamic Class Loading Example | ||
*/ | ||
@Test | ||
public void dynamicJavaClassLoader() throws Exception { | ||
JavaClassLoader loader = new JavaClassLoader(); | ||
loader.invokeClassMethod(JavassistUtil.SERVICE + "Hello", "say"); | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
jdk8/src/test/java/t5750/javassist/loader/JavaClassLoader.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package t5750.javassist.loader; | ||
|
||
import java.lang.reflect.Constructor; | ||
import java.lang.reflect.Method; | ||
|
||
public class JavaClassLoader extends ClassLoader { | ||
public void invokeClassMethod(String classBinName, String methodName) { | ||
try { | ||
// Create a new JavaClassLoader | ||
ClassLoader classLoader = this.getClass().getClassLoader(); | ||
// Load the target class using its binary name | ||
Class loadedMyClass = classLoader.loadClass(classBinName); | ||
System.out.println("Loaded class name: " + loadedMyClass.getName()); | ||
// Create a new instance from the loaded class | ||
Constructor constructor = loadedMyClass.getConstructor(); | ||
Object myClassObject = constructor.newInstance(); | ||
// Getting the target method from the loaded class and invoke it | ||
// using its name | ||
Method method = loadedMyClass.getMethod(methodName); | ||
System.out.println("Invoked method name: " + method.getName()); | ||
method.invoke(myClassObject); | ||
} catch (ClassNotFoundException e) { | ||
e.printStackTrace(); | ||
} catch (Exception e) { | ||
e.printStackTrace(); | ||
} | ||
} | ||
} |
46 changes: 46 additions & 0 deletions
46
jdk8/src/test/java/t5750/javassist/loader/SampleLoader.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package t5750.javassist.loader; | ||
|
||
import java.io.IOException; | ||
|
||
import javassist.CannotCompileException; | ||
import javassist.ClassPool; | ||
import javassist.CtClass; | ||
import javassist.NotFoundException; | ||
import t5750.javassist.util.JavassistUtil; | ||
|
||
public class SampleLoader extends ClassLoader { | ||
/* | ||
* Call MyApp.main(). | ||
*/ | ||
public static void main(String[] args) throws Throwable { | ||
SampleLoader s = new SampleLoader(); | ||
Class c = s.loadClass(JavassistUtil.SERVICE + "MyApp"); | ||
c.getDeclaredMethod("main", new Class[] { String[].class }).invoke(null, | ||
new Object[] { args }); | ||
} | ||
|
||
private ClassPool pool; | ||
|
||
public SampleLoader() throws NotFoundException { | ||
pool = new ClassPool(); | ||
pool.insertClassPath("./class"); // MyApp.class must be there. | ||
} | ||
|
||
/* | ||
* Finds a specified class. The bytecode for that class can be modified. | ||
*/ | ||
protected Class findClass(String name) throws ClassNotFoundException { | ||
try { | ||
CtClass cc = pool.get(name); | ||
// modify the CtClass object here | ||
byte[] b = cc.toBytecode(); | ||
return defineClass(name, b, 0, b.length); | ||
} catch (NotFoundException e) { | ||
throw new ClassNotFoundException(); | ||
} catch (IOException e) { | ||
throw new ClassNotFoundException(); | ||
} catch (CannotCompileException e) { | ||
throw new ClassNotFoundException(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package t5750.javassist.service; | ||
|
||
public class Hello { | ||
public void say() { | ||
System.out.println("Hello"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package t5750.javassist.service; | ||
|
||
public class MyApp { | ||
public static void main(String[] args) throws Exception { | ||
for (String str : args) { | ||
System.out.println("Hello " + str); | ||
} | ||
} | ||
|
||
public static void getHiddenValue() throws Exception { | ||
System.out.println(String.class.getField("hiddenValue").getName()); | ||
} | ||
} |
17 changes: 17 additions & 0 deletions
17
jdk8/src/test/java/t5750/javassist/service/impl/MyTranslator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package t5750.javassist.service.impl; | ||
|
||
import javassist.*; | ||
|
||
public class MyTranslator implements Translator { | ||
@Override | ||
public void start(ClassPool pool) | ||
throws NotFoundException, CannotCompileException { | ||
} | ||
|
||
@Override | ||
public void onLoad(ClassPool pool, String classname) | ||
throws NotFoundException, CannotCompileException { | ||
CtClass cc = pool.get(classname); | ||
cc.setModifiers(Modifier.PUBLIC); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,9 @@ | ||
package t5750.javassist.util; | ||
|
||
public final class JavassistUtil { | ||
public static final String DOMAIN = "t5750.javassist.domain."; | ||
public static final String JAVASSIST = "t5750.javassist."; | ||
public static final String DOMAIN = JAVASSIST + "domain."; | ||
public static final String SERVICE = JAVASSIST + "service."; | ||
public static final String POINT = "java.awt.Point"; | ||
public static final String[] ARGS = new String[] { "World", "T5750" }; | ||
} |