elasticsearch,Java,Web Services,elasticsearch" /> elasticsearch,Java,Web Services,elasticsearch" />

Java web服务中使用的ElasticSearch引发重叠FileLockException

Java web服务中使用的ElasticSearch引发重叠FileLockException,java,web-services,elasticsearch,Java,Web Services,elasticsearch,我们使用ElasticSearch编写了一个比较文档的库。它可以在JSF应用程序中工作,但不能在Web服务中工作 这两个应用程序具有相同的逻辑:首先,它们创建一个存储库(构造器从硬编码位置加载一个文档列表并为其编制索引),然后允许用户将自己的文档与存储库中的文档进行比较。JSF应用程序提供了一些GUI,但是webservice层非常薄——它在启动时创建存储库(加载和索引文档),然后将比较请求传递给库 更复杂的JSF应用程序工作起来没有任何问题,而webservice应用程序甚至不加载(即,它甚至

我们使用ElasticSearch编写了一个比较文档的库。它可以在JSF应用程序中工作,但不能在Web服务中工作

这两个应用程序具有相同的逻辑:首先,它们创建一个存储库(构造器从硬编码位置加载一个文档列表并为其编制索引),然后允许用户将自己的文档与存储库中的文档进行比较。JSF应用程序提供了一些GUI,但是webservice层非常薄——它在启动时创建存储库(加载和索引文档),然后将比较请求传递给库

更复杂的JSF应用程序工作起来没有任何问题,而webservice应用程序甚至不加载(即,它甚至不为文档编制索引),存在重叠锁的问题。(请注意,我部署了一个或另一个应用程序,而不是同时部署两个应用程序。这些应用程序不共享任何数据。我之所以提到JSF应用程序,是因为它可以工作,而另一个应用程序不能工作,即使它们使用相同的库。)

JSF应用程序和Web服务有什么不同,前者可以工作,而后者不能工作

以下是一些细节(稍微简化/修改)

网络服务:

@WebService(serviceName = "RepositoryWebService")
public class RepositoryWebService {
    private static Repository repository = Repository.getInstance();

    // some web methods (irrelevant since I never get that far)
}

public class Repository {
   private final static Repository instance = new Repository();

   public static Repository getInstance() {
       return instance;
   }
   :
}
JSF应用程序access还创建了一个存储库的单例实例(使用
@ApplicationScoped
bean)

Web服务的例外情况是:

java.nio.channels.OverlappingFileLockException
at sun.nio.ch.SharedFileLockTable.checkList(FileLockTable.java:255) [rt.jar:1.7.0_04]
    :
at java.nio.channels.FileChannel.tryLock(FileChannel.java:1154) [rt.jar:1.7.0_04]
at org.apache.lucene.store.NativeFSLock.obtain(NativeFSLockFactory.java:217) [lucene-core-3.6.1.jar:3.6.1 1362471 - thetaphi - 2012-07-17 12:40:12]
at org.elasticsearch.env.NodeEnvironment.<init>(NodeEnvironment.java:80) [elasticsearch-0.19.11.jar:]
at org.elasticsearch.node.internal.InternalNode.<init>(InternalNode.java:125) [elasticsearch-0.19.11.jar:]
at org.elasticsearch.node.NodeBuilder.build(NodeBuilder.java:159) [elasticsearch-0.19.11.jar:]
at org.elasticsearch.node.NodeBuilder.node(NodeBuilder.java:166) [elasticsearch-0.19.11.jar:]
at org.abc.Repository.<init>(Repository.java:56) [repository.jar:]
    :
我尝试了glassfish 3.1.2和JBoss 7.1.1,得到了相同的结果。两者都在JDK 1.7.0_07 64位Windows 7上

任何关于我做错了什么的建议都将不胜感激

更新:

当我将所有依赖jar(elasticsearch*、jna*、log4j*、lucene*、snappy java*和我的jar)放入域的lib目录(在Glassfish上)时,它就可以工作了。当jar只是war文件的一部分时,它就不存在了


不知道发生了什么事。我认为这可能与java中只加载了一个本机库实例有关,但仅加载jna和snappy java JAR是不够的。

对于JSF和Web服务应用程序,您似乎是在方法调用或类似调用之后加载列表。在最后一个示例中,您应该在部署应用程序时加载数据。为此,编写一个
ServletContextListener
并在
contextInitialized
方法中加载数据

ServletContextListener
将在Web应用程序中加载所有
Servlet
之前加载。通过这样做,您的所有web服务方法都可以访问准备好的数据

关于
ServletContextListener

如果需要/想要从Web服务类访问
ServletContext
,可以通过设置以下语句来实现

@WebService(serviceName = "RepositoryWebService")
public class RepositoryWebService {

    @Resource
    private WebServiceContext wsContext;

    @SuppressWarnings("unused")
    private ServletContext getServletContext() {
        return (ServletContext)wsContext.getMessageContext()
            .get(MessageContext.SERVLET_CONTEXT);
    }

    //your web methods here...
}

不确定这是否有帮助,但以下是一些想法:

  • 看起来您已经加载了webservice类的多个实例。您确定Repository.getInstance()工作正常吗
  • 我有一个演示项目(webapp-restwebservice+embedded-ES)可以工作:(看看这个)。我在这个项目中使用了Spring和Elasticsearch Spring工厂:

希望这能有所帮助。

但这就是静态变量
repository
自动执行的操作-当类加载器加载
RepositoryWebService
时,它会创建
repository
对象。
Repository
的构造函数加载文档(确实如此,一旦索引开始,问题就会出现)。您是否试图同时加载JSF和Web服务应用程序在同一台机器上的数据?否。我部署了其中一个。JSF工作,ws不工作。谢谢。是的,我非常确定存储库只创建了一次(构造函数中有一个log语句,我在日志中只看到一条这样的日志消息)。@dadoonet,您是否尝试过运行演示项目的多个实例?它有用吗?面对同样的问题,当尝试在tomcat中部署两个war文件实例(配置不同)时。我不知道(线程太旧),但elasticsearch不再支持嵌入。
@WebService(serviceName = "RepositoryWebService")
public class RepositoryWebService {

    @Resource
    private WebServiceContext wsContext;

    @SuppressWarnings("unused")
    private ServletContext getServletContext() {
        return (ServletContext)wsContext.getMessageContext()
            .get(MessageContext.SERVLET_CONTEXT);
    }

    //your web methods here...
}