Index > JavaでPluginを実現する方法(改良版)
Tue, April 22, 2008

JavaでPluginを実現する方法(改良版)

前回 の例では、 プラグインを使う側のクラスに プラグインしたクラス名を知らせる必要がありました。

今回は、その情報をプラグインjar(この例では mycolor.jar)から直接取得できるようにし、 プラグインを使う側は、単にプラグインされたjarファイル名だけを知っていれば プラグインを使えるように変更しました。

基本方針

前回とほとんど同じだが、mycolor.jar にマニフェスト情報としてプラグインするクラス名を 記述しておくことで、mycolor.jarだけ渡せば、プラグインを使えるようにする。

base.jarの用意

プラグインを作成する上で必要となるクラスを詰め込んだ base.jar を用意します。 また、そのプラグインを使うクラスも一緒に入れておきます。

base.jarの中には、以下の2つのクラスが入っています。

IFavoriteColor

public interface IFavoriteColor{
       String getColor();
}

PrintFavoriteColor

import java.io.*;
import java.net.*;
import java.util.jar.*;

public class PrintFavoriteColor{

    private File jarFile;
    private String className;

    public PrintFavoriteColor(File jarFile){
        this(jarFile,readClassName(jarFile));
    }
    static private String readClassName(File jarFile){
        try{
                JarFile jar = new JarFile(jarFile);
                Manifest manifest = jar.getManifest(); 
            Attributes attrs = manifest.getMainAttributes();//"Plugin-Class");
            String className = attrs.getValue("Plugin-Class");
            className=className.trim();
            return className;
        }
        catch(Exception e){ 
            e.printStackTrace();
        }
        return null;
    }

    public PrintFavoriteColor(File jarFile,String className){
        super();
        this.jarFile=jarFile;
        this.className=className;
    }

    public void print(){

        try{ 
            URL url = jarFile.toURL(); 
            URLClassLoader loader = new URLClassLoader(new URL[]{url}); 

            Class c = loader.loadClass(className); 
            Object obj = c.newInstance(); 
            IFavoriteColor fc=(IFavoriteColor)obj;
            System.out.println( " My favorite color is "+fc.getColor()+"." );
        }
        catch(Exception e){ 
            e.printStackTrace();
        }
    }

    public static void main(String[] args){
        if(args.length==1){
            String jarFileName=args[0];

            PrintFavoriteColor pfc=new PrintFavoriteColor(new File(jarFileName));
            pfc.print();
        }
        if(args.length==2){
            String jarFileName=args[0];
            String className=args[1];

            PrintFavoriteColor pfc=new PrintFavoriteColor(new File(jarFileName),className);
            pfc.print();
        }
    }


}

前回からの変更点

jarファイルをひとつだけを取るコンストラクタを追加しました。
また、 readClassName()というスタテックメソッドを追加して、このメソッド内で、 jarファイルからマニフェスト情報を読んで、クラス名を抽出しています。

base.jarの作成

$ javac -classpath base.jar IFavoriteColor.java PrintFavoriteColor.java
$ jar cf base.jar *.class

mycolor.jar の用意

IFavoriteColorを実装した MyFavoriteColor クラスを作成し、mycolor.jar に詰めます。
また、プラグイン対象となるクラス名を記述した manifest.stubファイルを作成します。

MyFavoriteColor

public class MyFavoriteColor implements IFavoriteColor{

       public String getColor(){
           return "blue";
       }
}

manifest.stub

Plugin-Class: MyFavoriteColor 

mycolor.jarの作成

$ javac -classpath base.jar MyFavoriteColor.java
$ jar cmf manifest.stub mycolor.jar *.class

※manifest.stubを含めて myclolor.jar を生成します。

作動確認

$ java -cp base.jar PrintFavoriteColor mycolor.jar
 My favorite color is blue.

前回 と異なりオプションには、mycolor.jar だけを与えます。

 Twitter
follow me on Twitter
 Categories