import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
public class ShowLoadProcess {
public static final String BR = "\r\n";
private static final String FILE_NAME = "HelloWorld";
public static void main(String[] args) throws Exception {
ShowLoadProcess main = new ShowLoadProcess();
main.showClassLoadProcess();
//gc
System.gc();
System.out.println("wait 10 seconds");
Thread.sleep( 10000 );
System.out.println("垃圾回收完成,开始重新部署");
main.reload();
System.out.println("垃圾回收完成,重新部署完成");
}
public void reload() {
try {
//1.生成java代码的字符串
String src = generatorCode2();
System.out.println( src );
//2.生成java文件
File javaFile = generateJavaFile( src, ShowLoadProcess.class, FILE_NAME );
//3.把java文件编译成class文件
compilerJavaFile( javaFile );
//4.定义自定义的类加载器把类文件记载到JVM
Class c = loadClass( ShowLoadProcess.class, FILE_NAME );
//5.create object according reflect
Constructor constructor = c.getConstructor();
Object o = constructor.newInstance();
Method method = c.getDeclaredMethod( "echo", String.class );
Object result = method.invoke( o, "hello,server" );
System.out.println( "receive:" + result );
//6.删除过程HelloWorld.java文件,删除Helloworld.class文件
//deleteTempFile( javaFile );
} catch (Exception e) {
e.printStackTrace();
}
}
public void showClassLoadProcess() {
try {
//1.generatecode
String src = generatorCode();
System.out.println( src );
//2.generate java file
File javaFile = generateJavaFile( src, ShowLoadProcess.class, FILE_NAME );
//3.complie java file to get class file
compilerJavaFile( javaFile );
// //4.define ownclassloader to load class file to jvm
Class c = loadClass( ShowLoadProcess.class, FILE_NAME );
//5.create object according reflect
Constructor constructor = c.getConstructor();
Object o = constructor.newInstance();
Method method = c.getDeclaredMethod( "echo", String.class );
Object result = method.invoke( o, "hello,server" );
System.out.println( "receive:" + result );
// //6.删除过程HelloWorld.java文件,删除Helloworld.class文件
// deleteTempFile( javaFile );
} catch (Exception e) {
e.printStackTrace();
}
}
private Class loadClass(Class clazz, String className) throws ClassNotFoundException {
String classpath = clazz.getClassLoader().getResource( "" ).getPath();
WzClassLoad paicClassLoad = new WzClassLoad( classpath );
String currentPath = ShowLoadProcess.class.getPackage().getName();
System.out.println( "currentPath:" + currentPath + "." + className );
Class c = paicClassLoad.findClass( currentPath + "." + className );
return c;
}
private void deleteTempFile(File javaFile) {
String javaFilePath = javaFile.getPath();
String classFileName = javaFilePath.substring( 0, javaFilePath.indexOf( "." ) ) + ".class";
javaFile.delete();
File classFile = new File( classFileName );
if (classFile != null) {
classFile.delete();
}
System.out.println( javaFilePath );
System.out.println( classFileName );
System.out.println( "文件删除成功" );
}
private void compilerJavaFile(File javaFile) {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
// System.out.println( javaFile.getPath() );
final int run = compiler.run( null, null, null, javaFile.getPath() );
System.out.println( run == 0 ? "编译成功" : "编译失败" );
}
private File generateJavaFile(String src, Class clazz, String javaFileName){
String classpath = clazz.getClassLoader().getResource( "" ).getPath();
System.out.println( "classpath:" + classpath );
String packageName = clazz.getPackage().getName();
String filePath = classpath + packageName.replaceAll( "[.]", "/" ) + "/" + javaFileName + ".java";
System.out.println( "HelloWorld.java file path:" + filePath );
File file = new File( filePath );
if (file.exists()) {
file.delete();
try {
file.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try
{FileWriter writer = new FileWriter( file );
writer.write( src );
writer.flush();
}catch (Exception e)
{
}
return file;
}
public String generatorCode_for_reload() {
StringBuffer sb = new StringBuffer();
sb.append( this.getClass().getPackage() ).append( ";" ).append( BR );
sb.append( "public class HelloWorld {" ).append( BR );
sb.append( "public String echo(String message) {" ).append( BR );
sb.append( "System.out.println(\"receive message:\"+message);" ).append( BR );
sb.append( "return \"hello,client2\";" ).append( BR );
sb.append( "}" ).append( BR );
sb.append( "}" ).append( BR );
return sb.toString();
}
public String generatorCode2() {
StringBuffer sb = new StringBuffer();
sb.append( this.getClass().getPackage().toString() ).append( ";" ).append( BR );
sb.append( "public class HelloWorld {" ).append( BR );
sb.append( "public String echo(String message) {" ).append( BR );
sb.append( "System.out.println(\"receive message2:\"+message);" ).append( BR );
sb.append( "return \"hello,client2\";" ).append( BR );
sb.append( "}" ).append( BR );
sb.append( "}" ).append( BR );
return sb.toString();
}
public String generatorCode() {
StringBuffer sb = new StringBuffer();
sb.append( this.getClass().getPackage().toString() ).append( ";" ).append( BR );
sb.append( "public class HelloWorld {" ).append( BR );
sb.append( "public String echo(String message) {" ).append( BR );
sb.append( "System.out.println(\"receive message1:\"+message);" ).append( BR );
sb.append( "return \"hello,client1\";" ).append( BR );
sb.append( "}" ).append( BR );
sb.append( "}" ).append( BR );
return sb.toString();
}
}
class WzClassLoad extends ClassLoader {
private String classpath;
public WzClassLoad(String classpath) {
this.classpath = classpath;
}
@Override
public Class<?> findClass(String name) {
//super.defineClass(name,)
String filePath = this.classpath + name.replaceAll("[.]","/")+".class";
FileInputStream fileInputStream = null;
try {
fileInputStream = new FileInputStream(filePath);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
int count =0;
byte[] bytes = new byte[1024];
try {
while (-1 != (count=fileInputStream.read(bytes))){
byteArrayOutputStream.write(bytes,0,count);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
byte[] resutBytes = byteArrayOutputStream.toByteArray();
return super.defineClass(name, resutBytes, 0, resutBytes.length);
}
}