Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 由于类加载器,在Tomcat web应用程序中实现单例模式时出现问题_Java_Tomcat_Servlets_Singleton_Classloader - Fatal编程技术网

Java 由于类加载器,在Tomcat web应用程序中实现单例模式时出现问题

Java 由于类加载器,在Tomcat web应用程序中实现单例模式时出现问题,java,tomcat,servlets,singleton,classloader,Java,Tomcat,Servlets,Singleton,Classloader,我试图在Linux上用x86_64 OpenJDK 1.6在Tomcat 6.24中实现一个单例 我的应用程序只是一堆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.su

我试图在Linux上用x86_64 OpenJDK 1.6在Tomcat 6.24中实现一个单例

我的应用程序只是一堆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>

应用程序名称
应用程序名称
pages/index.jsp
以前,当我尝试加载我的单例时,它被实例化了两次,因为类被两个不同的类加载器加载(我不知道为什么),每个加载器都会创建一个单例实例,这对于我的应用程序来说是不可接受的。我最终发现,如果我将代码导出为jar并将其放入$CATALINA_HOME/lib中,那么只有一个实例,但这不是一个优雅的解决方案


我在谷歌上搜索了几个小时,但还没有找到任何东西。我想知道是否还有其他解决办法。目前我没有预编译JSP,这可能是问题的一部分吗?我可以编写一个servlet来确保创建单例吗?如果是这样的话,我该怎么做?

什么时候第一次创建单例?在加载
index.jsp
时,可以通过包含以下内容强制创建它:

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

线路


如果预编译jsp并将tomcat配置为从不自动重新加载类或jsp,则单例应保持单例:-)

为确保单例的正确初始化,应检查是否使用默认的父级第一类加载器,请参阅

然后在方法中定义并初始化您的单例:

contextInitialized(ServletContextEvent sce)  
它保证在任何servlet或过滤器之前被调用

所有ServletContextListener都是 通知上下文初始化 在 web应用程序已初始化


在web.xml中定义ServletContextListener好的,我终于解决了问题

我已将我的应用程序添加到server.xml并将路径设置为“”,从而使我的应用程序成为服务器的默认应用程序。然而,当我通过一些东西的URL访问它时,也通过其他东西的URL访问它

有一次我改变了所有的URL来代替它,问题就解决了

有一次我改变了所有的URL来代替它,问题就解决了


这意味着您已经部署了2个Web应用程序,并期望它们使用相同的类加载器。这是不真实的。如果您想要一个所有Web应用程序都使用的共享库,那么应该将它放在“Tomcat shared”表示的路径中(可通过
catalina.properties
文件中的
shared.loader
进行配置)。你只需要确保你在webapp自己的库或Tomcat/lib中没有这个库。

你只有一个webapp,还是有多个webapp?只有一个webapp使用singleton多个jsp mae调用一个类的方法,该类在执行方法的过程中使用singleton。我将尝试对jsp进行预编译,看看这是否解决了问题。@jwegan,通过将其添加到加载的第一个jsp中,您将引入已知的第一次使用,以防止以后在应用程序流中出现可能的争用。jsp不必使用单例,只需强制在已知点对其进行实例化即可。我尝试放入index.jsp,当index.jsp加载时,构造函数似乎被调用了两次(通过在构造函数中打印到stderr来确认)。我创建单例作为类静态初始化的一部分,因此出于某种原因,似乎有两个类加载器参与提供索引。jsp@jwegan,您能打印到该点的堆栈跟踪吗?顺便说一句,对于singleton,最好在Synchronized getInstance()方法中创建singleton实例,以防止在应用程序启动时同时进行所有初始化。谢谢,您关于上下文的帖子让我意识到问题的存在是因为我是通过/和访问应用程序的/