ホットデプロイ

プログラム実行中にメソッドの中身を書き換えて反映させる.

ただ,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」に変更しても動かない.なぜだろうか… 現環境ではデフォルトパッケージでの動作を確認している.