ホットデプロイ
プログラム実行中にメソッドの中身を書き換えて反映させる.
ただ,eclipseでクラスローダを使用しようとするとパス関係でエラーを吐いたのでそこら辺を重点的に.
まず,書き換え対象ファイルが以下のMyHotDeploy.javaである.
MyHotDeploy.java
public class MyHotDeploy {
public void test(){
System.out.println("いろいろ変更可能");
}
}
このファイルをデスクトップのtestフォルダに保存しておく.
これに対して,ホットデプロイするためのソースが以下のMyCompiler.javaである.
MyCompiler.java
import java.io.File;
import java.lang.reflect.*;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Iterator;
import java.util.Scanner;
import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
public class MyCompiler {
public static void main(String[] args) throws Exception {
String targetFolder = "C:\\Users\\gutug_000\\Desktop\\test";
String targetClass = "MyHotDeploy";
String targetMethod = "test";
String targetFile = targetFolder + "\\" + targetClass + ".java";
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
if (compiler == null) {
System.out.println("compilerがnull");
return;
}
while (true) {
int ret = compiler.run(null, null, null,
new String[] { targetFile });
if (ret == 0) {
ClassLoader loader = URLClassLoader.newInstance(
new URL[] { new File(targetFolder).toURI().toURL() },
null);
Class<?> clazz = Class.forName(targetClass, true, loader);
if (clazz != null) {
Method method = clazz.getMethod(targetMethod);
if (method != null) {
method.invoke(clazz.newInstance());
}
}
}
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
break;
}
}
}
}
コンパイラーがnull返す場合はここを参考にしてeclipseの設定を変更して欲しい.
上のソースは1秒ごとにクラスを再ロード,メソッドを呼び出して実行するというソース.
これを実行することで(ほぼ)リアルタイムでソースの変更を監視することが可能になる.
main文の冒頭の3行を適宜変更することによって対応して欲しい.
さて,上のMyHotDeploy.java,一応eclipseで管理されるワークスペースにおいてあるものを引用することも可能であるが,どこかのパッケージの中に入ってるとクラスローダがエラーを吐いてしまう.targetClassを「(パッケージ名).MyHotDeploy」や「(パッケージ名)/MyHotDeploy」に変更しても動かない.なぜだろうか… 現環境ではデフォルトパッケージでの動作を確認している.