Tue, April 22, 2008
JavaでPluginを実現する方法(改良版)
前回 の例では、 プラグインを使う側のクラスに プラグインしたクラス名を知らせる必要がありました。
今回は、その情報をプラグインjar(この例では mycolor.jar)から直接取得できるようにし、 プラグインを使う側は、単にプラグインされたjarファイル名だけを知っていれば プラグインを使えるように変更しました。
基本方針
前回とほとんど同じだが、mycolor.jar にマニフェスト情報としてプラグインするクラス名を 記述しておくことで、mycolor.jarだけ渡せば、プラグインを使えるようにする。
base.jarの用意
プラグインを作成する上で必要となるクラスを詰め込んだ base.jar を用意します。 また、そのプラグインを使うクラスも一緒に入れておきます。
base.jarの中には、以下の2つのクラスが入っています。
- IFavoriteColor.class (プラグインが実装すべきインタフェース)
- PrintFavoriteColor.class (プラグインを使うためのクラス)
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 だけを与えます。