コーディング例

以下のような構造のアーカイブ・ファイルを考えます。

/
+---classes/
|   +---クラス・ファイル
+---lib/
    +---jarファイル

以下の要件のサーバ・クラスを書くことを考えます。

  • サーバ・クラスのFQNは"example.ExampleServer"とします。
  • このアーカイブ・ファイルをdeployディレクトリに配置すると、workディレクトリに展開し、クラスローダを構築し、別スレッドでMainクラスのexecute()メソッドを呼び出します。
  • deployディレクトリに配置されたアーカイブ・ファイルを削除すると、workディレクトリに展開されたファイルが削除され、クラスローダが破棄されます。
このようなサーバは、以下のようなコードで実現できます。
package example;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

import jp.sourceforge.deployer.Deployer;
import jp.sourceforge.deployer.DeployerClassLoader;
import jp.sourceforge.deployer.DeployerListener;

public class ExampleServer implements DeployerListener {

    private static Deployer                  deployer;

    private Map<String, DeployerClassLoader> appMap = new HashMap<String, DeployerClassLoader>();

    public static void main(String[] args) throws Exception {
        File deployDir = new File("./deploy");
        Pattern filePattern = Pattern.compile(".*\\.jar");
        File workDir = new File("./work");

        deployer = new Deployer(deployDir, filePattern, workDir);
        deployer.addListener(new ExampleServer());

        while (true) {
            deployer.monitor();
            Thread.sleep(1000);
        }
    }

    public void deployEnd(Deployer deployer, File file, File destDirectory) {
        try {
            System.out.println("deployEnd: " + file.getAbsolutePath());

            File[] fileDirectories = new File[] { new File(destDirectory, "classes") };
            File[] jarDirectories = new File[] { new File(destDirectory, "lib") };

            final DeployerClassLoader cl = new DeployerClassLoader(fileDirectories, jarDirectories);

            this.appMap.put(file.getAbsolutePath(), cl);

            Runnable r = new Runnable() {

                public void run() {
                    try {
                        Class clazz = cl.loadClass("Main");
                        Object obj = clazz.newInstance();
                        clazz.getMethod("execute").invoke(obj);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

            };
            Thread t = new Thread(r);
            t.start();
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }

    public void deployFile(Deployer deployer, File file, File destDirectory, File deployFile) {
        System.out.println("deployFile: " + deployFile.getAbsolutePath());
    }

    public void deployStart(Deployer deployer, File file) {
        System.out.println("deployStart: " + file.getAbsolutePath());
    }

    public void undeployEnd(Deployer deployer, File file) {
        System.out.println("undeployEnd: " + file.getAbsolutePath());

        DeployerClassLoader cl = this.appMap.get(file.getAbsolutePath());
        cl.dispose();
    }

    public void undeployStart(Deployer deployer, File file, File destDirectory) {
        System.out.println("undeployStart: " + file.getAbsolutePath());
    }

}