6
  • 私の/tomcat/libディレクトリにはクラスSharedClassがあります(したがって、すべてのWebアプリと共有されます)。
  • 私のWebアプリWEB-INF/libには class がありLocalClassます。
  • SharedClassへの参照がありLocalClassます。

私のWebアプリでは、のインスタンスを作成しようとしましたSharedClassが、次のメッセージで失敗しました:

NoClassDefFoundError: LocalClass.

SharedClassは共有されておりLocalClass、私の Web アプリに対してローカルであるため、機能することを望んでいましたが、機能しません 。

私の疑いではSharedClass、Tomcat の親クラスローダーLocalClassによってロードされ、Web アプリ クラスローダーによってロードされます。親によってロードされたのでSharedClass、そのすべての依存関係も親によってロードされる必要があると思います。したがって、親は見つけることができずLocalClass、エラーをスローします。

これは理にかなっていますか?これを回避する方法はありますか (独自のクラスローダーを作成せずに)?

4

3 に答える 3

7

ClassLoaderは階層的です。クラスローダーには親があり、その親のクラスを参照します。逆は当てはまりません。したがって、Webアプリケーションのクラスローダーによってロードされたクラスは、JREクラス(Tomcatのクラスローダーの親)にアクセスできる共通のTomcatクラスローダー(その親)によってロードされたクラスにアクセスできます。

詳細については、TomcatのドキュメントClassLoaderjavadocを参照してください。

于 2013-01-11T22:13:00.430 に答える
3

これは理にかなっており、Tomcatがアプリケーションを分離できる方法です。詳細については、http://tomcat.apache.org/tomcat-6.0-doc/class-loader-howto.htmlを参照してください。

共有クラスがアプリケーションクラスをロードしたり、アプリケーションクラスのインスタンスを作成したりする正当な理由はほとんどありません。これを行う必要があるまれなケースでは、を呼び出すことができますThread.getCurrentThread().getContextClassloader()


編集:キャンプファイヤーを始めたい人にLOXに浸した練炭を渡しているような気がするので、共有クラスローダーからアプリケーションクラスをロードするのが悪い考えである理由は次のとおりです。

差し迫った問題は、クラスを共有クラスローダーに実際にロードしていないため、作成したオブジェクトを簡単に操作できないことです。代わりに、リフレクションを使用してメソッドを呼び出す必要があります。これにより、コードが混乱します。

ただし、さらに悪い問題は、SharedClassインスタンスがのインスタンスへの参照を維持している場合LocalClass、それらの参照によってTomcatがアプリケーションをアンデプロイできないことです。実際には、アンデプロイすると主張しますが、それらの参照が収集されるまで、古いアプリケーションの一部がpermgenに存在し続け、permgenの枯渇につながることがよくあります。

したがって、コンテキストクラスローダーは便利なツールであり、クラスパスリソースにアクセスする唯一の方法である必要がありますが、これは簡単に問題を引き起こす可能性のあるツールです。

于 2013-01-11T22:13:08.737 に答える
0

通常の Java アプリケーションでは、クラスローダがクラスをロードするように求められると、要求をその親クラス ローダに委譲し、親クラス ローダが要求されたクラスを見つけられない場合はそれをロードします。

Web アプリケーション サーバーの場合、これは少し異なります。通常、Tomcat などの Web アプリケーション サーバーにデプロイされた各 Web アプリには、異なるクラス ローダーがあります。Tomcatの場合、以下のようになります-

ここに画像の説明を入力

したがって、Web アプリのクラスの読み込みリソースの場合、次の順序でリソースが読み込まれます -

  1. JVM のブートストラップ クラス (コア Java クラス)
  2. Web アプリケーションの /WEB-INF/classes
  3. Web アプリケーションの /WEB-INF/lib/*.jar
  4. システム クラス ローダー クラス (Tomcat / クラスパス固有のクラス)
  5. 共通のクラス ローダー クラス (すべての Web アプリに共通のクラス)

ただし、Web アプリケーション クラス ローダーが構成されているdelegate="true"場合は、順序が変更されることに注意してください -

  1. JVM のブートストラップ クラス (コア Java クラス)
  2. システム クラス ローダー クラス (Tomcat / クラスパス固有のクラス)
  3. 共通のクラス ローダー クラス (すべての Web アプリに共通のクラス)
  4. Web アプリケーションの /WEB-INF/classes
  5. Web アプリケーションの /WEB-INF/lib/*.jar

詳細については、Apache Tomcat のClass Loader HOW-TOページを確認してください。

于 2015-02-22T16:08:28.077 に答える