несколько корневых корневых WebApplicationContexts - PullRequest
3 голосов
/ 02 декабря 2010

У меня есть сервер Tomcat с двумя веб-приложениями (foo и bar), которые ведут одинаковую войну развертывания.Развертывание использует стандартную настройку Spring / Hibernate.Я предполагал, что эти два веб-приложения будут запускаться и работать совершенно независимо друг от друга, но это не так - веб-приложение foo загружается нормально, но панель веб-приложений имеет какое-то странное поведение - как если бы она использовала одни и те же компоненты из веб-приложенияFoo.Например, когда запускается bar (запускается 2-е веб-приложение), c3p0 жалуется, что оно уже зарегистрировано - предположительно в веб-приложении foo.Опять же, я пытаюсь сделать два веб-приложения полностью независимыми, чтобы у двух компонентов c3p0 / hibernateSessionFactory не было возможности узнать друг о друге.

Проводя некоторые исследования, я руководствовалсяполагать, что один и тот же корень Spring WebApplicationContext используется в обоих веб-приложениях.Если это так, как я могу сделать каждое веб-приложение (на том же сервере 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>

1 Ответ

1 голос
/ 02 декабря 2010

У меня есть подозрение.Разве загрузка классов не является корнем вашей проблемы?

Я полагаю, что прямая причина вашей проблемы заключается в том, что какой-то класс Spring загружается один раз и распределяется между этими двумя WAR.Я не знаю точного имени класса, но Spring должен хранить некоторую общую информацию (по крайней мере, ссылку на контекст приложения) в некотором статическом поле.Затем, когда две WAR видят одну и ту же копию класса, оба приложения видят одно и то же состояние этого статического поля.Я предполагаю, что в вашей настройке Spring создает только один контекст приложения (когда должен быть создан второй, Spring находит существующий контекст приложения и использует его вместо этого).

Я вижу две возможные причины такой проблемы:

  • либо это проблема загрузки классов.Я не настолько увлечен tomcat и не знаю, как и если вы можете настроить это, но обычно на серверах приложений JavaEE есть какой-то способ настроить загрузку классов для WAR.
  • , или это своего рода утечка памяти.Возможно, класс (и его статическое поле) повторно используется из какого-то предыдущего развертывания (маловероятно, что ваше описание склоняется к тому, что вы сталкиваетесь с проблемой на новом экземпляре tomcat).Вы можете исключить эту возможность, убедившись, что проблема появляется сразу после того, как вы (пере) запустили tomcat.

ОБНОВЛЕНИЕ: Если речь идет о загрузке классов, я бы попытался выяснить, какой класс (иего статическое поле) вызывает проблемы.Вероятно, это не ваш класс, а какой-то сторонний библиотечный класс, который вы используете в своем приложении.После прочтения http://tomcat.apache.org/tomcat-6.0-doc/class-loader-howto.html вы увидите, что Tomcat использует разные не связанные загрузчики классов для каждого приложения.Однако оба они совместно используют загрузчики родительских классов, которым они делегируют, если они не знают класс.Опять же, я не знаю ваших точных настроек и некоторых особенностей Tomcat, но ... Разве в Tomcat невозможно поместить некоторую библиотеку (JAR), такую ​​как c3p0 или Spring, в какую-нибудь общую папку 'lib' (в документации сказано:$ CATALINA_HOME / Lib)?В таком случае классы из этих JAR-файлов загружаются с использованием загрузчика родительского класса (тот, который называется 'Common' в документации tomcat).Это означает, что они загружаются только один раз.

Короче говоря, я предполагаю, что причина в том, что один из JAR-файлов в вашем $ CATALINA_HOME / lib имеет некоторый класс, который сильно зависит от некоторых статических полей.Политика Tomcat для загрузки JAR-файлов, использующих общий загрузчик классов, приводит к тому, что все приложения разделяют состояние этих статических полей.

Я говорил вам, что это только подозрение и предположение?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...