kontext-e / jqassistant-gradle-plugin

Gradle Plugin for jQAssistant
3 stars 3 forks source link

Classpath issues if APOC is declared in .jqassistant.yml #16

Open DirkMahler opened 1 month ago

DirkMahler commented 1 month ago

jQA allows declaration of additional Neo4j plugins in .jqassistant.yml, a typical one is APOC:

jqassistant:
  store:
    embedded:
      neo4j-plugins:
        - group-id: org.neo4j.procedure
          artifact-id: apoc-core
          classifier: core
          version: ${neo4j-apoc.version}      

This works with the jQA Maven plugin as well as with the "pure" CLI but currently fails with the Gradle plugin.

The reason for that is a restriction of Neo4j which requires plugins to be available via the application classloader (just dropping the artifacts into the Neo4j plugin folder sadly is not enough). Therefore the jQA CLI extends the classpath using the Java Instrumentation API, relying on an according declaration in the JAR manifest, see https://github.com/jQAssistant/jqassistant/blob/master/cli/neo4jv5/pom.xml#L35. As far as I can see the Gradle plugin runs the CLI directly by referencing the Main class but bypassing that declaration.

I'd like to discuss an effective solution about howto make the resolved plugin artifacts available on the classpath. This does not necessarily means to use the instrumentation mechanism, I am open to find more elegant solutions.

WilliamThimm commented 1 month ago

Hello @DirkMahler

Thank you for pointing that out. Unfortunately, my understanding of the mechanisms involved in loading the neo4j plugins is quite limited. I have looked at the code you referenced, as well as the InstrumentationProvider, and I understand how it is used. Unfortunately, I do not understand the mechanisms regarding the JAR manifest. When and how is the InstrumentationProvider loaded in the normal CLI distribution, and how would this translate to the approach taken by this gradle plugin? As far as I know, there is no direct mechanism to register this launcher agent directly through gradle. I have tried to pass the agent as a JVM arg using the -javaagent argument, but unfortunately, the argument requires the location of the jar containing the agent, which is not always easily obtainable.

I would highly appreciate your help, so I can improve the plugin.