1

動的に記述およびロードされる拡張機能をサポートする JAR アプリケーション M.jar があります。アプリケーションでは、クラスがインターフェイス E を実装し、NE と呼ばれることが必要です。

今、私がやろうとしていることは次のとおりです。

  1. 拡張 API1 を作成し、M にロードします。
  2. 別の拡張 APIUser を作成し、それを M にロードして、API1 を使用します。

私がここでやろうとしていることについては、下の図を参照してください。

ここに画像の説明を入力

M.jar はカスタム ClassLoader を使用することを知っています。これは、拡張子を AE のみにする必要があるためです。

I tried the ServiceProvider, ServiceProviderInterface method as described here but that did not work. I believe this is because API's classes are not in M's classpath and hence APIUser cannot find it.

I want to know,

  1. If it is feasible to use APIUser's ClassLoader to load API's class and initialize it for use in APIUser.
  2. Is it possible for M to block/isolate API's ClassLoader from any other extensions? I think it can be based off of this answer.
  3. What other means are there to load API's class in APIUser1 or APIUSer2 ... and maintain only one instance of API's class? (i.e singleton)
4

1 に答える 1

0

ClassLoader について調査し、調べた結果、質問に関して学んだことを以下に示します。

  1. M.jar や他の拡張可能な Java プログラムが別のプログラムをロードする方法は、URLClassLoader を他の ClassLoader の子として使用しているためです。これは、ClassLoader 委任階層では、API.jar の ClassLoader が階層の上位に位置し、APIUser.jar の ClassLoader が兄弟になることを意味します。これは、API.jar からロードされたクラスが APIUser.jar に表示されないことを意味します。

  2. M は拡張機能を明示的に分離しませんが、JAR をアプリケーションにロードする自然な方法です。

  3. 質問 1 への回答に基づいて、私が現在行っている方法は、実行時に JAR を SystemClassLoader のクラスパスに追加し、SystemClassLoader を使用してそれをロードすることにより、他の拡張機能から参照するというハックな方法を使用することです。これは、SystemClassLoader がどの拡張機能からも見えるためです。

注: また、これを行う ServiceLoader の方法も機能すると想定しています。しかし、私はそれを自分で試したことはありません。

参考文献:

https://zeroturnaround.com/rebellabs/rebel-labs-tutorial-do-you-really-get-classloaders/

https://docs.oracle.com/javase/8/docs/api/java/lang/ClassLoader.html

于 2018-06-18T01:47:03.010 に答える