プラグインの作成

トップ > チップス > プラグインの作成
2012-02-13, make-plugins eclipse

プラグインプロジェクトを作成する

「New Project -> Plug0in Development -> Plug-in Project」からEclipseのプラグイン開発用のプロジェクトを生成することが出来ます。

クラスパス変数を追加する

適当なサンプルを元にプラグインプロジェクトを生成し、「org.eclipse.jdt.core」をDependenciesに追加します。続いて以下の拡張ポイントをExtensionsに登録します。一部の要素はExtensionsタブ上のエディタでは追加できず、直接plugins.xmlを編集する必要があります。また、スペルミス等があってもエラーは出ず、登録されないだけの状態になることに注意して下さい。

<extension
  point="org.eclipse.jdt.core.classpathVariableInitializer">
  <classpathVariableInitializer
    class="jp.co.lumber_mill.FoobarVariableInitializer"
    variable="FOOBAR" />
</extension>

上記で指定したイニシャライザ(クラス)は以下のように定義します(エラー処理等は省いてあります)。

public class FoobarVariableInitializer extends ClasspathVariableInitializer{

  public static final String VARIABLE_NAME = "FOOBAR";

  @Override
  public void initialize(String arg0) {
    String fullPath = new File("C:\\Program Files\\lumber-mill.co.jp\\foobar").getAbsolutePath();
    try {
      JavaCore.setClasspathVariable(VARIABLE_NAME, new Path(fullPath),null);
    } catch (JavaModelException e) {
      JavaCore.removeClasspathVariable(VARIABLE_NAME,null);
    }
  }

}

以上で、完成です。プラグインが読み込まれるとクラスパス変数に「FOOBAR」が追加されています。「Preferences -> Java -> Build Path -> Classpath Variables」から確認することができます。

Package Explorerのポップアップメニューにアクションを追加する

規定のプラグインプロジェクト(Plugin with popup menu)を作成し、plugin.xmlの以下(太字)の箇所を修正します。

<objectContribution
  objectClass="{strong:org.eclipse.jdt.core.IJavaElement}"
  id="jp.co.lumber_mill.foo.contribution1">

Jarファイルを生成する

自力でzipファイルを作ってjarにリネームした方が早いかもしれませんが・・・、一応JDTにもjar生成を支援するクラス(JarPackageData)が存在します。以下は、binフォルダに出力されたクラスファイルをjarにパッケージする例です。プロジェクトのルートが強制的にjarのルートになってしまうため、クラスファイルを追加する場合は色々と配慮が必要です。

IJavaProject jp = .. // selection等から、JavaProjectを取得
JarPackageData jpd = new JarPackageData();
// 出力先設定
IPath target = jp.getProject().getLocation().append("foo.jar");
jpd.setJarLocation(target);
// 出力対象リソースの登録
try {
  IPath output_path = jp_required.getOutputLocation();
  IFolder output_folder = (IFolder) jp_required.getProject().getWorkspace()
      .getRoot().findMember(output_path);
  LinkedList<Object> list = new LinkedList<Object>();
  findElements(output_folder, list);
  jpd.setElements(list.toArray());
} catch (JavaModelException e) {
  showErrorDialog(e, shell);
  return;
} catch (CoreException e) {
  showErrorDialog(e, shell);
  return;
}
// クラスファイルを出力対象に
jpd.setExportOutputFolders(true);
// 処理の実行
IJarExportRunnable runnable = jpd.createJarExportRunnable(shell);
try {
  new ProgressMonitorDialog(shell).run(true, true, runnable);
} catch (InvocationTargetException e) {
  showErrorDialog(e, runnable.getStatus(), shell);
  return;
} catch (InterruptedException e) {
}
private static void findElements(IResource ir, List<Object> list)
    throws CoreException {
  if (ir instanceof IFolder) {
    for (IResource irr : ((IFolder) ir).members()) {
      findElements(irr, list);
    }
  } else if (ir instanceof IFile) {
    IFile ifile = (IFile) ir;
    IClassFile cf = JavaCore.createClassFileFrom(ifile);
    list.add(cf);
  } else {
    System.err.println("Unknown: " + ir);
  }
}

プラグイン開発時にソースコードを確認できるようにする

以下のパッケージを使用すると、プラグインの作成時にEclipseプラットフォーム(org.eclipse.jdtパッケージとか)のソースコードとドキュメントを参照できるようになります。

Eclipse for RCP/Plug-in Developers

ソースコード自体も一つのプラグインとしてeclipse内部に含まれているようなので、必要な部分をコピーできれば、他のパッケージでも同様に使用できるようになると思われます。

捕捉されなかったRuntimeExceptionを確認する

プラグインで発生した例外はcatchされない限り、コンソール等に出力されることがないようです。そういった例外は「{workspace}/.metadata/.log」に保存されています。

外部のライブラリを追加する

>2008.09.01追加 >この方法でも、結局、別環境に配備した際にClassNotFoundExceptionが発生します。共有する外部のライブラリも、それぞれ別個のプラグインとして準備する必要があるようです。

プラグインプロジェクトでは「Build Path」メニューから他のプロジェクトやライブラリを指定しても、実行時にクラスパスに追加されずClassNotFoundExceptionが発生してしまいます。代わりにプロジェクト内の任意のフォルダにjarファイルを配備した後に、RuntimeタブのClasspathに追加する必要があります。

プラグイン読み込み時のエラーを確認する

Help → About Eclipse Platform → Configuration Detailsで起動時のログを確認することが出来ます。さらに「View Error Log」をからエラーを確認できます。配備したプラグインが正常に起動しない場合はここを調べましょう。

プラグインの更新を反映する

pluginsフォルダにインストールしたプラグインを更新した場合、eclipse.exeに「-clean」オプションを付けて起動します。これをしないと、古いバージョンの動作をしてしまうことがあるようです(一体何処にキャッシュがあるのでしょう?)。

> eclipse.exe -clean

バックグラウンドで処理を行う

以下は、時間のかかる処理を起動し進捗をダイアログに表示するサンプルです(Thread.sleepしているだけですが)。IProgressMonitorのメソッドを適切に呼び出すことで、より細かい進捗をユーザに伝えることができます。

IRunnableWithProgress rwp = new IRunnableWithProgress(){
  @Override
  public void run(IProgressMonitor monitor)
      throws InvocationTargetException, InterruptedException {
    monitor.beginTask("Main Task", 5);
    monitor.subTask("Sub Task 1");
    monitor.worked(1);
    Thread.sleep(500);
    monitor.worked(1);
    Thread.sleep(500);
    monitor.worked(1);
    Thread.sleep(500);
    monitor.subTask("Sub Task 2");
    Thread.sleep(500);
    monitor.worked(1);
    Thread.sleep(500);
    monitor.worked(1);
    Thread.sleep(500);
    monitor.done();
  }};

ProgressMonitorDialog dialog = new ProgressMonitorDialog(window.getShell());
try {
  dialog.run(true, false, rwp);
} catch (InvocationTargetException e) {
  e.printStackTrace();
} catch (InterruptedException e) {
  e.printStackTrace();
}

この記事は役に立ちましたか?