0

我通过 Alex Smirnov neo4j JCA 连接器的修改版本在 glassfish 服务器中使用 neo4j。我的版本在这里可用:https ://github.com/Riduidel/neo4j-connector 我正在将此连接器与 neo4j 1.8 一起使用。因此,当我想使用它时,我首先在我的 Glassfish 应用程序服务器中安装连接器,然后在希望连接的应用程序中使用此连接器。

与新鲜商店一起使用时效果很好。但是,当将它与使用以前版本创建的商店一起使用时,我遇到了奇怪的错误。

通常,我今天得到以下堆栈

javax.resource.spi.ResourceAllocationException: Error in allocating a connection. Cause: Failed to transition org.neo4j.kernel.InternalAbstractGraphDatabase$DefaultKernelExtensionLoader@3bbd53b1 from NONE to STOPPED
...
...
.../* JCA internal exception stack */
...
...
Caused by: com.sun.appserv.connectors.internal.api.PoolingException: Failed to transition org.neo4j.kernel.InternalAbstractGraphDatabase$DefaultKernelExtensionLoader@494b584c from NONE to STOPPED
 at com.sun.enterprise.resource.pool.ConnectionPool.createSingleResource(ConnectionPool.java:924)
 at com.sun.enterprise.resource.pool.ConnectionPool.createResource(ConnectionPool.java:1185)
 at com.sun.enterprise.resource.pool.datastructure.RWLockDataStructure.addResource(RWLockDataStructure.java:98)
 ... 66 more
Caused by: org.neo4j.kernel.lifecycle.LifecycleException: Failed to transition org.neo4j.kernel.InternalAbstractGraphDatabase$DefaultKernelExtensionLoader@494b584c from NONE to STOPPED
 at org.neo4j.kernel.lifecycle.LifeSupport$LifecycleInstance.init(LifeSupport.java:388)
 at org.neo4j.kernel.lifecycle.LifeSupport.init(LifeSupport.java:82)
 at org.neo4j.kernel.lifecycle.LifeSupport.start(LifeSupport.java:116)
 at org.neo4j.kernel.InternalAbstractGraphDatabase.run(InternalAbstractGraphDatabase.java:227)
 at org.neo4j.kernel.EmbeddedGraphDatabase.<init>(EmbeddedGraphDatabase.java:79)
 at org.neo4j.kernel.EmbeddedGraphDatabase.<init>(EmbeddedGraphDatabase.java:70)
 at com.netoprise.neo4j.AbstractNeo4jManagedConnectionFactory.createDatabase(AbstractNeo4jManagedConnectionFactory.java:165)
 at com.netoprise.neo4j.AbstractNeo4jManagedConnectionFactory.createDatabase(AbstractNeo4jManagedConnectionFactory.java:127)
 at com.netoprise.neo4j.Neo4jManagedConnectionFactory.createManagedConnection(Neo4jManagedConnectionFactory.java:163)
 at com.sun.enterprise.resource.allocator.ConnectorAllocator.createResource(ConnectorAllocator.java:160)
 at com.sun.enterprise.resource.pool.ConnectionPool.createSingleResource(ConnectionPool.java:907)
 ... 68 more
Caused by: java.lang.AssertionError
 at org.neo4j.index.impl.lucene.LuceneDataSource.cleanWriteLocks(LuceneDataSource.java:265)
 at org.neo4j.index.impl.lucene.LuceneDataSource.cleanWriteLocks(LuceneDataSource.java:260)
 at org.neo4j.index.impl.lucene.LuceneDataSource.cleanWriteLocks(LuceneDataSource.java:260)
 at org.neo4j.index.impl.lucene.LuceneDataSource.cleanWriteLocks(LuceneDataSource.java:260)
 at org.neo4j.index.impl.lucene.LuceneDataSource.<init>(LuceneDataSource.java:185)
 at org.neo4j.index.lucene.LuceneIndexProvider.load(LuceneIndexProvider.java:72)
 at org.neo4j.kernel.InternalAbstractGraphDatabase$DefaultKernelExtensionLoader.loadIndexImplementations(InternalAbstractGraphDatabase.java:1171)
 at org.neo4j.kernel.InternalAbstractGraphDatabase$DefaultKernelExtensionLoader.init(InternalAbstractGraphDatabase.java:1143)
 at org.neo4j.kernel.lifecycle.LifeSupport$LifecycleInstance.init(LifeSupport.java:382)
 ... 78 more

快速检查显示此异常与不可删除的“write.lock”文件相关联。我的 write.lock 文件无法删除,因为我猜迁移还没有结束。如何确保在使用之前完成迁移而不将其迁移到 Glassfish 之外?

有没有办法在这种情况下进行独家商店迁移?如果是这样,如何?它是我问题的解决方案吗?

编辑 1添加了异常消息。

编辑 2所有这一切只发生在加载的图形以前与 Neo4j 1.5 一起使用,现在与 Neo4j 1.8 连接器一起使用时。当连接器创建图形时,绝对不会发生错误。

编辑 3奇怪的是,只要没有调试器插入该代码就会发生这种情况:只要我尝试调试它,问题就会停止出现。这让我想到可能有一种迁移清理机制,一旦迁移完成,它就会删除写锁,并且在使用我的 neo4j JCA 连接器时不会执行此清理。这是一个有效的观察吗?

4

2 回答 2

1

我对 JCA 连接器不太熟悉,但可以肯定的是,我只会编写一个非常小的迁移 java 类来打开数据库,让它迁移和关闭。然后用 JCA 连接器再试一次?

于 2013-04-08T12:38:54.980 回答
0

经过进一步调查,事实表明并非多次调用EmbeddedGraphDatabase构造函数,而是IndexProvider加载了多个身份。

我使用嵌入在开源 JCA 连接器中的 neo4j。在此连接器中,org.neo4j.kernel.Service该类被一个自定义类替换,其中包含有关 JBoss 非共享库的服务加载的解决方法。不幸的是,在我们的上下文中,这种解决方法意味着加载两次索引提供程序:

  1. 曾经使用 EAR 类加载器
  2. 曾经使用 Glassfish 库类加载器。

为什么 ?因为,当我们的 neo4j 实例用于应用程序数据和身份验证时,neo4j 连接器 jar 被放入${domain}/lib. 因此,由于应用服务器中的 Classloader 委托,EAR 类加载器委托给 Glassfish 库类加载器,并以这种方式找到LuceneIndexProvider. 然后,直接使用 Glassfish 库类加载器来加载同一个LuceneIndexProvider类。

结论是我们有两个LuceneIndexProvider对象,都试图迁移 lucene 索引。这导致第一个对象创建AssertionErrorwrite.lock文件应该被第二个对象删除,这是不能做到的。

然后,我稍微更改了那个非常具体的类,以仅在默认加载机制不返回任何类时才使用 JBoss 解决方法(请参阅此处的提交)。这个小改变就像一个魅力,所以我认为你可以认为这个问题已经解决了。

于 2013-04-16T08:11:08.767 回答