2016-09-01 6 views
1

私は、戦争、1つのjarに多数のサービスBeanを持つコアejb、別のjarのリモートインタフェースで構成されるアプリケーションを持っています。すべてが耳に入っていて、Glassfish 4.1で動作しています。CDIインスタンスイテレータを使用したJava EEプラグインフレームワーク

ここでは、拡張ポイントまたはプラグインのサポートをコアejbに追加します。

目的は、すべて同じインタフェースを共有する異なるホットプラグ可能なデータインポートサービスを持つことです。これは、ロイターとブルームバーグのようなベンダーの財務データをフェッチして正規化するためです。

これらのプラグインは、コアejb jarの「Plugin Manager」Beanによって検出および管理される必要があります。プラグインは、実行時にロード、アンロード、および置換をサポートする必要があります。

プラグインインターフェイスは別々のパッケージになっているのが理想的です。私のアプリケーションやGlassfishを使わずに誰かが開発でき、Java EEスタックがなくても完璧です。私はまた、アプリケーション全体ではなく、いつでもプラグインを展開したいと思っています。

現在、私はコアejbにある限り、2つのインポートサービスの実装でうまく動作するCDIインスタンスイテレータを使用しようとしています。ある実装を別のejb jarファイルに入れると、それは単にCDIには見つかりません。私は問題はGlassfishが別のクラスローダーのアプリケーションとして各ejb jarをロードすることだと思います。

現在、現在の簡略化されたコードがあります。

別のJARパッケージのプラグインインタフェース:

package com.photon.extensions; 

import java.io.Serializable; 

public interface ImportServiceExtension extends Serializable { 
    String getImportServiceName(); 
} 

見出されていない別のEJB JARパッケージのプラグインの実装:

package com.photon.services.extensions.vitrex.services; 

import com.photon.extensions.ImportServiceExtension; 
import javax.ejb.Remote; 
import javax.ejb.Stateless; 

@Remote(ImportServiceExtension.class) 
@Stateless 
public class ReutersImportService implements ImportServiceExtension { 
    @Override 
    public String getImportServiceName() { 
     return "Reuters"; 
    } 
} 

コアEJBジャーにおけるプラグインの実装見つかったパッケージ:

package com.photon.services.extensions; 

import com.photon.extensions.ImportServiceExtension; 
import javax.ejb.Stateless; 

@Stateless 
public class BloombergImportService implements ImportServiceExtension { 
    @Override 
    public String getImportServiceName() { 
     return "Bloomberg"; 
    } 
} 

リモートリモートインタフェースジャー中の「プラグインマネージャ」のためのインターフェース:

package com.photon.services.extensions; 

import java.util.List; 
import javax.ejb.Remote; 

@Remote 
public interface ImportServiceExtensionsRemote { 
    List<String> getImportServiceNames(); 
} 

コアEJBジャー中の「プラグインマネージャ」bean実装:

package com.photon.services.extensions; 

import com.photon.extensions.ImportServiceExtension; 
import java.util.ArrayList; 
import java.util.Iterator; 
import java.util.List; 
import javax.ejb.Stateless; 
import javax.enterprise.inject.Instance; 
import javax.inject.Inject; 

@Stateless 
public class ImportersService implements ImportServiceExtensionsRemote { 

    @Inject private Instance<ImportServiceExtension> importServiceExtensions; 

    @Override 
    public List<String> getImportServiceNames() { 
     Iterator<ImportServiceExtension> iter = importServiceExtensions.iterator(); 
     List<String> names = new ArrayList<>(); 
     while (iter.hasNext()) { 
      ImportServiceExtension extension = iter.next(); 
      names.add(extension.getImportServiceName()); 
     } 
     return names; 
    } 
} 

そして最後に名前をレンダリングコントローラ

最終的には「ブルームバーグ」のみがレンダリングされます。

今私の質問:

  1. 私は正しい軌道に乗っていますか?

  2. もしそうなら、コードには何がありますか?

  3. この問題(OSGI、カスタム 、clazz.forNameなど)の方が良い解決策がありますか?

答えて

1

私はあなたに完全な答えを与えるが、ここで思考のためのいくつかの食品であることができない...

私は問題はGlassfishのは別々のクラスローダで アプリケーションとして各EJB jarファイルをロードすることであると思います。

あなたはそれを釘付けにしました。残念ながら、これはのJEE仕様であるため、予期した動作です。

Glassfishについてはわかりませんが、配置間でクラスローダーを共有できる機能があるかもしれません(Wildflyにはデプロイメントアイソレーションと呼ばれるものがあります)。それはあなたの問題を解決するかもしれません。

私がWildflyから知っていることは、サーバモジュールとしてデプロイされたアプリケーションを他のすべてのデプロイメント(およびそのクラスローダー)にアクセスできるようにすることです。グラスフィッシュに似たものがあれば、それを試すことができます。あなたがワイルドフライにショットを出そうとしている場合には、hereはこれが議論された場所へのリンクです。今

ビューのCDIの観点から、この動作でも正確であり、あなたが持っていた場合は、他の展開(からクラスローダへのアクセスを持っていないので、私は、あなたがそれを変えることができる方法はありません怖いです指定されたデプロイメントのためにBeanManagerをロードし、関連するBeanを検索することができます)。

これは少なくともあなたにいくつかの洞察を与えてくれることを願っています。

+0

ありがとう!私はこのWildFlyを見ていきます。 – IUnknown

関連する問題