Проблема реализации шаблона Singleton в веб-приложении Tomcat из-за Class Loader - PullRequest
1 голос
/ 04 мая 2010

Я пытаюсь реализовать Singleton в Tomcat 6.24 для Linux с x86_64 OpenJDK 1.6.

Мое приложение - это просто набор JSP и некоторый статический контент, и JSP выполняют вызовы моего Java-кода. В настоящее время web.xml выглядит так:

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
   version="2.5">

<description>
    App Name
</description>
<display-name>App Name</display-name>

<!-- The Usual Welcome File List -->
<welcome-file-list>
    <welcome-file>pages/index.jsp</welcome-file>
 </welcome-file-list>

</web-app>

Раньше, когда я пытался загрузить мой Singleton, он дважды создавался, поскольку класс загружался двумя различными загрузчиками классов (я не уверен почему), и каждый загрузчик создавал экземпляр singleton, что неприемлемо для моего приложения. Наконец-то я понял, что если я экспортировал свой код в виде jar-файла и поместил его в $ CATALINA_HOME / lib, тогда был только один экземпляр, но это не элегантное решение.

Я часами гуглял, но пока ничего не придумал. Мне интересно, есть ли какое-то другое решение. В настоящее время я не выполняю предварительную компиляцию своих JSP, может ли это быть частью проблемы? Могу ли я написать сервлет, чтобы убедиться, что синглтон создан? Если да, то как мне это сделать?

Ответы [ 4 ]

2 голосов
/ 04 мая 2010

Хорошо, я наконец-то понял проблему.

Я сделал свое приложение приложением по умолчанию для сервера, добавив в server.xml и указав путь к «». Однако, когда я получал к нему доступ через URL http://localhost/somepage.jsp для некоторых вещей, но также и для URL http://localhost/appname/anotherpage.jsp для других вещей.

После того как я изменил все URL-адреса, чтобы использовать http://localhost/ вместо http://localhost/appname, проблема была исправлена.

1 голос
/ 04 мая 2010

Чтобы обеспечить правильную инициализацию Singleton, вы должны убедиться, что вы используете загрузчик классов по умолчанию для первого родителя, см. http://tomcat.apache.org/tomcat-6.0-doc/class-loader-howto.html.

Затем определите ServletContextListener и инициализируйте ваш Singleton в методе:

contextInitialized(ServletContextEvent sce)  

, который гарантированно будет вызываться перед любым из ваших сервлетов или фильтров.

Все ServletContextListeners являются уведомление о инициализации контекста перед любым фильтром или сервлетом в веб-приложение инициализировано.

Определите ваш ServletContextListener в вашем web.xml

0 голосов
/ 04 мая 2010

После того как я изменил все URL-адреса, чтобы использовать http://localhost/ вместо http://localhost/appname, проблема была исправлена.

Это означает, что вы развернули 2 веб-приложения и ожидали, что они будут использовать один и тот же загрузчик классов. Это неправда. Если вам нужна разделяемая библиотека, которая используется всеми веб-приложениями, вы должны поместить ее в путь, обозначенный как «Tomcat Shared» (который настраивается shared.loader в catalina.properties файле) Вам нужно только убедиться, что у вас , а не , есть эта библиотека в собственной библиотеке веб-приложения или в Tomcat / lib.

0 голосов
/ 04 мая 2010

Когда синглтон создается первым? Вы можете принудительно создать его при загрузке index.jsp, добавив:

<%! MySingleton instance = MySingleton.getInstance(); %>

линия.

Если вы предварительно скомпилируете jsp и сконфигурируете tomcat, чтобы никогда не перезагружать классы, или jsp синглтон должен оставаться одиночным: -)

...