neo4j 程序取决于已签名的 jar (mapdb)

neo4j procedure depending on signed jar (mapdb)

我创建了一个 neo4j 用户定义过程。它还可以在 neo4j 中编译和工作。

虽然最近,我向我的程序插件添加了一个依赖项,以防止 neo4j 在我尝试 运行 新构建的 jar 时启动。具体来说,我在堆栈跟踪的底部收到以下异常:

Caused by: java.lang.SecurityException: Invalid signature file digest for Manifest main attributes

我唯一改变的是将 MapDB 添加到我的依赖项中。所以我怀疑它取决于一些签名的工件。事实证明,neo4j 插件是 "uber-jars"(即阴影罐),它不能很好地与签名的依赖项一起工作。

我想我可以通过将范围更改为 provided 并将 mapdb jar 添加到 neo4j 的插件文件夹中来尝试将 MapDB 从阴影中排除。所以 neo4j 的 plugins 文件夹现在包括 mapdb.jarmyprocedure.jar.

虽然这似乎不起作用:neo4j 启动,但在调用我的过程时我收到一个 ClassNotFound 异常。

关于如何解决这个难题有什么想法吗?我真的很依赖像 MapDB 这样的东西,因为我的图表非常大,并且将我的过程中的所有内容保存在内存中经常会导致内存异常。

非常感谢!


我的 pom.xml 的重要部分应该有帮助(我从 procedure template 开始,所以它看起来仍然很相似):

<dependencies>

        <!-- other dependencies that don't make a difference ... -->

        <dependency>
            <groupId>org.mapdb</groupId>
            <artifactId>mapdb</artifactId>
            <version>3.0.7</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.neo4j</groupId>
            <artifactId>neo4j</artifactId>
            <version>${neo4j.version}</version>
            <scope>provided</scope>
        </dependency>

        <!-- Test Dependencies -->
        <dependency>
            <groupId>org.neo4j.test</groupId>
            <artifactId>neo4j-harness</artifactId>
            <version>${neo4j.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.neo4j.driver</groupId>
            <artifactId>neo4j-java-driver</artifactId>
            <version>1.4.2</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <!-- Neo4j Procedures require Java 8 -->
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <!-- This generates a jar-file with our procedure code,
                     plus any dependencies marked as `compile` scope.
                     This should then be deployed in the `plugins` directory
                     of each Neo4j instance in your deployment.
                     After a restart, the procedure is available for calling. -->
                <artifactId>maven-shade-plugin</artifactId>
                <version>2.4.3</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

因此,一种有效的解决方案是使用 maven-assembly-plugin 而不是 maven-shade-plugin。 assembly 插件创建一个包含所有依赖项的独立 jar,而无需重新打包所有依赖项。

当然,我必须删除 mapdb 的 <scope>provided</scope>,所以它也包含在组装的 jar 中。

剩下的就是用下面的片段替换阴影插件(感谢这个question here):

<plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>single</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
    </configuration>
</plugin>

之后我收到另一个异常,我认为是由于错误的签名:

Caused by: java.lang.VerifyError ...

原来这只是因为我在 neo4j 中有另一个过程使用与 mapdb 相同的依赖项。快速修复是删除该过程库。

当然还有其他解决办法,包括去掉签名,或者重新签名。但是,我明确不想删除任何签名。

我不知道 neo4j 默认会检查任何 jar 签名。我怀疑 mapdb 工件的重新打包是罪魁祸首。

要验证这一点,请删除阴影或程序集插件并构建一个仅包含您的代码的 jar。将该 jar mapdb.jar 复制到插件文件夹中,并在重启期间观察日志。