Using apoc function with embedded database

Hello,

Currently working with Spring Data Neo4j, I'm using neo4j in 4.4.4.
I need to use an apoc coll function in a test. As this function is not bring by a simple import, I need to import in my pom.xml apoc with classifier all :

    <dependency>
	  <groupId>org.neo4j.procedure</groupId>
      <artifactId>apoc</artifactId>
	  <version>4.4.0.3</version>
	  <scope>test</scope>
	  <classifier>all</classifier>
	</dependency>

But this bring an old version of neo4j Driver (4.0.0) witch create conflict and result in unexecutable query.
It seem that this old version of neo4j is used for all latest apoc version.
Is there any chance for this to be updated?
Is there any way of getting only procedure and function class from the repository?

In advance thank you for your help.

This problem will be solve soon. See the question here on the projects github :

It seems that with Neo4j 5.x it is at least not trivial to get it up and running. I followed the approach documented here, but I'm running into several issues, e.g. classloading and injectables not being resolvable.

I created a demonstrator on GitHub - just clone and build it using "mvn clean verify" (JDK 17 required). Any hints?

(Hi Dirk :wave: :smile: )

As Michael points out in his example code here neo4j-examples-and-tips/examples/testing-ogm-against-embedded-with-apoc/src/test/java/org/neo4j/tips/testing/testing_ogm_against_embedded_with_apoc/ApplicationTests.java at d1dace775ca88441d6680e2bb3a9c9e11edfa8fc · michael-simons/neo4j-examples-and-tips · GitHub

dumping it in the plugins folder would not work because APOC needs some extension factories

Taken his approach on putting it in your application as a dependency and retrieving the plugin folder from an APOC class works.

With a lot of copy and pasting from the linked version this should happen before the db start (note the new pluginDir definition).

var pluginDirContainingApocJar = new File(
    ApocConfig.class.getProtectionDomain().getCodeSource().getLocation().toURI())
    .getParentFile().toPath();

var pluginDir = Files.createTempDirectory("neo4j-apoc-");
Files.find(pluginDirContainingApocJar, 1, (p, a) -> p.getFileName().toString().endsWith("-core.jar"))
    .forEach(p -> {
        try {
            Files.copy(p, pluginDir.resolve(p.getFileName()));
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    });

Also in your pom, as you have already added but commented out:

<dependency>
    <groupId>org.neo4j.procedure</groupId>
    <artifactId>apoc-core</artifactId>
    <classifier>core</classifier>
    <version>5.16.1</version>
</dependency>

needs to be in place.

Hi Gerrit (nice to meet you!),

thanks for your answer but actually it is bad news: Our use case is to enable dynamic provisioning of APOC (or other plugin JARs) for jQAssistant based on a configuration that we evaluate at runtime. So we have the problem that we don't know up-front the dependencies that we need to add... :frowning:

The interesting part is that I did not stumble upon missing services etc. but at classloading issues like this (indicating that a class references a package-private super class from another classloader):

Suppressed: java.lang.IllegalAccessError: class io.netty.buffer.UnsafeDirectLittleEndian cannot access its superclass io.netty.buffer.WrappedByteBuf (io.netty.buffer.UnsafeDirectLittleEndian is in unnamed module of loader org.neo4j.procedure.impl.ProcedureClassLoader @3f3c5ecd; io.netty.buffer.WrappedByteBuf is in unnamed module of loader 'app')

BTW: I was actually wondering why APOC works in the Neo4j distribution itself but I found the solution here where a classpath is constructed including the JARs from the plugin directory.

I have solution at hand that I didn't want to use in first place before asking if there's something better available. Let's see if it works out, if you're interested I can let you know.

Cheers

Dirk

I updated the demonstrator, a bit of ugly reflection based classloader hacking...