2010-12-02 12 views
3

私は同じ展開戦争の2つのWebアプリケーション(fooとbar)を持つTomcatサーバーを持っています。デプロイメントは、標準のSpring/Hibernate設定を使用します。私はこれらの2つのWebアプリケーションが起動し、互いに独立して動作することを前提としていましたが、そうではありません - webapp fooは通常どおりロードされますが、webapp barにはいくつかの奇妙な動作があります。 foo。たとえば、バーが起動すると(2番目のwebappが開始されます)、c3p0はすでに登録されていると苦情を言います。おそらくwebapp fooにあります。もう一度、2つのWebアプリケーションを完全に独立させようとしています.2つのc3p0/hibernateSessionFactory Beanが互いに知り合う方法がないはずです。複数のSpringルートWebApplicationContexts

私は、いくつかの研究を行う中で、両方のWebアプリケーションで同じSpringルートWebApplicationContextが使用されていると考えられています。その場合、どうすれば各Webアプリケーションを(同じTomcatサーバー上で)互いに完全に独立させることができますか?この問題の原因となるものは他にありますか? web.xmlファイルから

関連抜粋:

<web-app> 
    <context-param> 
     <param-name>org.hibernate.tags.sessionFactory</param-name> 
     <param-value>hibernate/SessionFactory</param-value> 
    </context-param> 

    <context-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value>/WEB-INF/context/*Context.xml</param-value> 
    </context-param> 

    <listener> 
     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
    </listener> 

    <servlet> 
     <servlet-name>fooServlet</servlet-name> 
     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
     <load-on-startup>1</load-on-startup> 
    </servlet> 
</web-app> 
+0

「既に登録されていると文句を言う」とはどういう意味ですか?例外?その場合は、例外を表示してください。 – skaffman

+0

「c3p0の行に沿った何かがすでに登録されているという警告がログに記録されています - コンテキストが正しくアンロードされずにメモリリークが発生する可能性があります」 少し正確なログメッセージが表示されます – Keith

+0

正確な警告は次のとおりです。 com.mchange.v2.c3p0.management.ActiveManagementCoordinator:56 - C3P0Registry mbeanはすでに登録されています。これはおそらく、c3p0を使用するアプリケーションがアンデプロイされたことを意味しますが、アンデプロイメント前にすべてのPooledDataSourcesが閉じられているわけではありません。これにより、時間の経過とともにリソースリークが発生する可能性があります。すべてのPooledDataSourceを閉じるよう注意してください。 – Keith

答えて

1

私はsuspisionを持っています。あなたの問題のルートをクラスローディングしていないのですか?

あなたの問題の直接の理由は、Springクラスが一度読み込まれ、これらの2つのWARの間で共有されるということです。クラスの正確な名前はわかりませんが、Springではいくつかの静的フィールドにいくつかの共有情報(少なくともアプリケーションコンテキストへの参照)を格納する必要があります。次に、2つのWARが同じクラスのコピーを参照すると、両方のアプリケーションはこの静的フィールドの同じ状態を参照します。あなたのセットアップでは、Springがアプリケーションコンテキストを1つだけ作成すると思います(2つ目は作成する必要があり、Springは既存のアプリケーションコンテキストを見つけて代わりに使用します)。

  • はどちらか、これはクラスローディングの問題です:

    は、私はこのような問題のための潜在的な二つの理由を参照してください。私はTomcatには入っておらず、あなたがそれを設定できるかどうかの手掛かりはありませんが、通常はJavaEEアプリケーションサーバでは、WARのクラスローディングを設定するいくつかの方法があります。

  • これは一種のメモリリークです。クラスとその静的フィールドが以前のいくつかのデプロイメントから再利用されている可能性があります(まれに、Tomcatの新しいインスタンスで問題が発生する可能性があります)。あなたは、あなたの(再)開始された風車の直後に問題が現れることを確認することによって、この可能性を排除することができます。

更新: これは、クラスロードに関するもので、どのクラス(およびその静的フィールド)が問題を引き起こしているかを調べようとします。これはおそらくあなたのクラスではなく、アプリケーションで使用するサードパーティのライブラリクラスです。 http://tomcat.apache.org/tomcat-6.0-doc/class-loader-howto.htmlを読んだあと、Tomcatは各アプリケーションに関連のない別のクラスローダーを使用していることがわかります。ただし、クラスを知らない場合は、両方が委譲する親クラスローダを共有します。 また、私はあなたの正確な設定といくつかのTomcatの特質を知らないけど... Tomcatでは、c3p0やSpringのようなライブラリ(JAR)をいくつかの一般的な 'lib'フォルダ(docs $ CATALINA_HOME/libと言っていますか?そのような場合、これらのJARのクラスは、親クラスローダー(Tomcatドキュメント内の 'Common'と呼ばれるもの)を使用してロードされます。つまり、それらは一度だけロードされます。

ストーリーを短くするためには、あなたの$ CATALINA_HOME/libにあるJARの1つにいくつかの静的フィールドに大きく依存するクラスがあると思います。 Commonクラスローダーを使用してJARをロードするTomcatポリシーは、すべてのアプリケーションがこれらの静的フィールドの状態を共有する結果となります。

これは唯一の疑いであり、推測していますか?

+0

最初の理由が考えられる。 Grzegorzが中止した場所を選ぶために、誰かがtomcatにwebappごとに異なるクラスローダーを使う方法を知っていますか? – Keith

+1

@Keith、あなたは$ CATALINA_HOME/libにSpringやc3p0を入れましたか(他の手段で持っていますか?) –

+0

私は$ CATALINA_HOME/libに珍しいことは何も持っていません。私の瓶がそれぞれのWebアプリケーション(彼らがいる)にある限り、紛争はないはずです。たぶんこれはc3p0/hibernate固有の問題です。 – Keith

関連する問題