我们使用Apache ServiceMix 5.3.0运行模块化应用程序平台。我需要使用持久性服务扩展我们的系统 - 所以我想构建一个包含Neo4J 2.1.6的OSGi包。
在我的pom.xml
(Maven)中我使用maven-bundle-plugin
(org.apache.felix)来构建捆绑包。我已将neo4j-kernel
和neo4j-lucene-index
个库中的几乎所有包添加到<Export-Package>
部分。
部署后,我的捆绑包显示在&#34;已解决&#34;州。但是,当它开始时它会抛出这个:
org.osgi.framework.BundleException: Activator start error ...
...
Caused by: java.lang.ArrayIndexOutOfBoundsException: 0
at org.neo4j.graphdb.factory.GraphDatabaseSettings.<clinit (GraphDatabaseSettings.java:69)
我的激活码如下所示(异常发生在最后一个命令):
GraphDatabaseFactory factory = new GraphDatabaseFactory();
/*
ArrayList<CacheProvider> caches = new ArrayList();
caches.add(new SoftCacheProvider());
factory.setCacheProviders(caches);
*/
GraphDatabaseBuilder builder = factory.newEmbeddedDatabaseBuilder("neo4j-db");
graphDb = builder.newGraphDatabase();
(如果评论的部分是否有效,则没有任何区别。)
错误模式与this question中的错误模式类似。
我怀疑来自org.neo4j.graphdb.factory.GraphDatabaseSettings
(第259f行)的以下方法中的恶魔无法找到任何CacheProvider
个实例,尽管它们在我的包中被打包并引用(org.neo4j.kernel.impl.cache...
):
private static String[] availableCaches()
{
List<String> available = new ArrayList<>();
for ( CacheProvider cacheProvider : Service.load( CacheProvider.class ) )
{
available.add( cacheProvider.getName() );
}
...
return available.toArray( new String[available.size()] );
}
我认为这是一个OSGi类加载器问题,而不是Neo4J问题。任何想法如何在这里继续?
答案 0 :(得分:1)
我设法同时解决了我的问题。正如Neil所说,它既不是OSGi问题,也不是Neo4J错误。相反,我必须学习更多关于Neo4J如何绑定其扩展以及如何相应地塑造OSGi依赖关系以获得成功的课程。
这些是我昨天研究的结果:
我的错误是依靠maven-bundle-plugin
的能力来解析项目并自动将所有内部依赖关系分解为包级别(这是OSGi所必需的)。这适用于由import
语句声明的类关系,但是,当然,在使用反射方法绑定外部内容时会失败。
由于应用程序在我的JUnit环境中运行良好,我的问题的原因必须包括OSGi环境中缺少的资源。
解决方案是虔诚地列出插件Export-Package
,Private-Package
和Import-Package
部分中每个库的每个单独的包(列表相当长),而不是信任通配符。
听从上述话题,我摆脱了上面提到的ArrayIndexOutOfBoundsException
,但我遇到了其他(类似的)异常。在我了解了Neo4J的“内核扩展”概念后,我获得了成功。
Neo4J(我有2.1.6版本)引入了“内核扩展”来连接可交换模块,以便在运行时进行缓存和索引。为了应用某个扩展,只需要将相应的jar添加到类路径中。每个库在META-INF/services
下携带一个或多个描述符文件,告诉可用的实现。这些文件由内核查找和处理,以便查找和绑定其扩展(索引和缓存的扩展是必需的)。
在我安全地将所有必要的java软件包包含在我的bundly之后,只有META-INF/services
中的描述符文件丢失了。 This code向我展示了如何将这些资源添加到捆绑包中(在<Embed-Dependency>
中搜索maven-bundle-plugin
部分。
Neo4J libs还包含一个蓝图描述符,用于自动将主要类作为服务发布(例如GraphDatabaseFactory)。这些资源位于OSGI-INF/blueprint/
下,也应包含在捆绑包中。
我的Neo4J OSGi包的最终pom.xml
如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>my.group</groupId>
<artifactId>neo4jBundle</artifactId>
<version>0.1.0</version>
<packaging>bundle</packaging>
<properties>
<neo4j-version>2.1.6</neo4j-version>
<lucene-version>3.6.2</lucene-version>
</properties>
<dependencies>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-kernel</artifactId>
<version>${neo4j-version}</version>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-lucene-index</artifactId>
<version>${neo4j-version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-Name>org.neo4j.kernel</Bundle-Name>
<Export-Package>org.neo4j.graphdb.*;version=${neo4j-version},
... {all neo4j packages} ...
org.apache.lucene;version=${lucene-version},
... {all lucene packages} ...
org.slf4j.impl
</Export-Package>
<Private-Package>
javax.transaction,
javax.transaction.xa,
ch.qos.logback.classic,
... {all logback.classic packages} ...
ch.qos.logback.core,
... {all logback.core packages} ...
org.slf4j.*
</Private-Package>
<Import-Package>
javax.lang.model,
... {some javax packages to be imported from the runtime} ...
!sun.misc,
... {exclude uneccessary packages to limit dependency} ...
*
</Import-Package>
<Embed-Dependency>
*;groupId=org.neo4j;artifactId=neo4j-kernel;inline=META-INF/services/*,
*;groupId=org.neo4j;artifactId=neo4j-kernel;inline=OSGI-INF/blueprint/*,
*;groupId=org.neo4j;artifactId=neo4j-lucene-index;inline=META-INF/services/*,
*;groupId=org.neo4j;artifactId=neo4j-lucene-index;inline=OSGI-INF/blueprint/*
</Embed-Dependency>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>
备注:这是一个纯库包,没有任何其他代码。我使用Activator的应用程序位于一个单独的包中。 这个例子只显示我解决问题的方法。我的例子并没有声称可以生成通用的Neo4J软件包。根据您想要的功能以及运行时已部署的东西的社会,您可能需要添加或省略某些包以使一切正常工作。