Jetty8.1.1サーバーが組み込まれたOSGiアプリケーションがあります。
アプリケーションをモノリット(OSGi環境なし)として実行すると、org.eclipse.jetty.servlet.ServletContextHandler.addServlet(String className, String mapping)
メソッドを呼び出すことでサーブレットを正常に登録できます。だから今、私はOSGi環境で同じことをしようとしています。
目標は、servlet-extender
起動時に他のバンドルによって提供されるサーブレットを登録するバンドル()を作成することです(エクステンダーパターン)。したがって、私のアプリケーションが起動した後、(とりわけ)実行されている必須のバンドルは2つだけです:jetty
とservlet-extender
。
書き込みの最初の試みservlet-extender
:
MANIFEST.MF
最初に、サーブレットを提供するバンドルのファイルで、マッピングを使用してサーブレットを宣言することにしました。そのようなバンドルが開始されると、サーブレットマッピング宣言をservlet-extender
検索します。MANIFEST.MF
サーブレットマッピング宣言が見つかった場合はservlet-extender
、前述のServletContextHandler.addServlet(...)
メソッドを呼び出して実際にサーブレットを登録します。
アイデアは問題ないように見えましたが、クラスの読み込みに問題があります。実際、Jettyはを呼び出しますClass.forName("org.my.servlets.MyServletClass").newInstance()
。バンドルはパッケージをインポートしませんが、呼び出しはjetty
で失敗します。org.my.servlets
Class.forName("org.my.servlets.MyServletClass")
ClassNotFoundException
2回目の書き込みの試みservlet-extender
:
OSGiでのクラスのロードに関連するいくつかの記事を検索しました。これは、いくつかのOSGiサービスを介してロードされたサーブレットクラスを提供することにより、以前の問題を解決できるという希望を私に与えました。そこで、メソッドServletProvider
を使用してサービスを作成しましたMap<Class<? extends Servlet>, String> getServlets()
(メソッドは、コンテキストにマップされたサーブレットクラスを返すだけです)。次にservlet-extender
、でサーブレットマッピングを検索しないように変更しましたMANIFEST.MF
。ServletProvider
バンドルが実装を登録するまで待つようになりました。そのようなサービスがOSGiサービスレジストリに登録されている場合servlet-extender
は、そのメソッドを呼び出して、getServlets()
返されたサーブレットクラスをに登録しようとしますjetty
。jetty
今は呼び出す必要はありませんが、サーブレットをインスタンス化Class.forName("org.my.servlets.MyServletClass")
するために呼び出す必要があります。servletClass.newInstance()
そして残念ながらそれはまだ失敗しますClassNotFoundException
。
バンドルがパッケージjetty
をインポートする場合、これは解決できることを理解しています。ただし、バンドルがサードパーティによって提供されてorg.my.servlets
いる間はこれは不可能であり、その宣言を変更することはできません。jetty
Import-Package
任意のバンドルによって提供されるサーブレットを動的に登録するにはどうすればよいですか?
PS:Jettyの8.1.1 WebSocketServletを使用する必要があるため、「OSGiHttpService」を使用できません。