SDN 5.1.0 + OGM 3.1.3 fails to load beans


(Mike Blum+Neo4j) #1

build.gradle looks like this:

  // use latest OGM version
//  compile "org.neo4j:neo4j-ogm-api:${ogmVersion}"
//  compile "org.neo4j:neo4j-ogm-core:${ogmVersion}"
//  compile "org.neo4j:neo4j-ogm-bolt-driver:${ogmVersion}"
//  compile "org.neo4j:neo4j-ogm-embedded-driver:${ogmVersion}"
//  compile "org.neo4j:neo4j-ogm-http-driver:${ogmVersion}"

  compile "org.springframework.data:spring-data-neo4j:5.1.0.RELEASE"

//  compile("org.springframework.data:spring-data-neo4j:5.1.0.RELEASE") {
//    exclude group: "org.neo4j", module: "neo4j-ogm-api"
//    exclude group: "org.neo4j", module: "neo4j-ogm-core"
//    exclude group: "org.neo4j", module: "neo4j-ogm-bolt-driver"
//    exclude group: "org.neo4j", module: "neo4j-ogm-embedded-driver"
//    exclude group: "org.neo4j", module: "neo4j-ogm-http-driver"
//  }

I've attempted to force SDN to use the latest OGM using the commented out sections.

java.lang.NoSuchMethodError: org.springframework.data.neo4j.repository.config.Neo4jRepositoryConfigurationExtension.registerWithSourceAndGeneratedBeanName(Lorg/springframework/beans/factory/support/AbstractBeanDefinition;Lorg/springframework/beans/factory/support/BeanDefinitionRegistry;Ljava/lang/Object;)Ljava/lang/String;
	at org.springframework.data.neo4j.repository.config.Neo4jRepositoryConfigurationExtension.registerWithGeneratedNameOrUseConfigured(Neo4jRepositoryConfigurationExtension.java:235)
	at org.springframework.data.neo4j.repository.config.Neo4jRepositoryConfigurationExtension.registerBeansForRoot(Neo4jRepositoryConfigurationExtension.java:193)
	at org.springframework.data.repository.config.RepositoryConfigurationDelegate.registerRepositoriesIn(RepositoryConfigurationDelegate.java:114)
	at org.springframework.data.repository.config.RepositoryBeanDefinitionRegistrarSupport.registerBeanDefinitions(RepositoryBeanDefinitionRegistrarSupport.java:85)
	at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.lambda$loadBeanDefinitionsFromRegistrars$0(ConfigurationClassBeanDefinitionReader.java:360)
	at java.util.LinkedHashMap.forEach(LinkedHashMap.java:684)
	at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsFromRegistrars(ConfigurationClassBeanDefinitionReader.java:359)
	at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:144)
	at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:117)
	at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:328)
	at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:233)
	at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:273)
	at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:93)
	at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:693)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:531)
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140)
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752)
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:388)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:327)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1246)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1234)

(Mike Blum+Neo4j) #2

Upgrading SDN to get to OGM 3.1.3 to resolve this issue: https://github.com/neo4j/neo4j-ogm/issues/437 BUT going to SDN 5.1.0 seems to have some configuration issues with the repositories?

If maven is to be believed the OGM version embedded into SDN 5.1.0 should be OGM 3.1.3? https://mvnrepository.com/artifact/org.springframework.data/spring-data-neo4j/5.1.0.RELEASE


(Gerrit Meier) #3

Can you please explain what happens in more detail? I really do not get the difference between using the commented version vs. enable the commented lines if 3.1.3 is really defined.
SDN 5.1.0 depends on Neo4j-OGM 3.1.3. There is no need to specify it manually (although you could do this).


(Mike Blum+Neo4j) #4

When i specify 31.3. explicitly or specify SDN 5.1.0 I get the above stack trace when I try to start my
Spring app (Spring Boot 2.0.0 RELEASE). I got it working with this SDN version + ordering:

// graph
compile "org.neo4j.driver:neo4j-java-driver:1.5.1"

compile "org.springframework.data:spring-data-neo4j:5.0.5.RELEASE"
annotationProcessor "org.neo4j:neo4j:${neo4jVersion}"
compileOnly "org.neo4j:neo4j:${neo4jVersion}"
compile "org.neo4j:neo4j-ogm-core:3.1.3"

Which resolves the #437 issue that i was trying to solve for originally. looks like weird things happen when I tried to use SDN 5.1.0.


(Gerrit Meier) #5

I am pretty sure that the problem is based in Spring (Boot):
Spring Boot 2.0.x is based on Spring Framework 5.0.x (works with SDN 5.0.x)
Spring Boot 2.1.x is based on Spring Framework 5.1.x (works with SDN 5.1.x)

When you pull in SDN 5.1 you also have two Spring Frameworks in you class path and this will end up in real bad application behaviour.


(Gerrit Meier) #6

Please ignore the reply above (more or less): I was wrong that SDN 5.1 will only work with Boot 2.1.
It is possible to use this as described in this blog post: https://spring.io/blog/2018/09/21/spring-data-lovelace-ga-released
I would suggest using the release train definition as described in the post instead of defining the version of SDN directly.

We (thanks to @michael.simons) tried to reproduce your problem and came up with a minimal example that works:

build.gradle

buildscript {
    ext {
        springBootVersion = '2.0.5.RELEASE'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 10

repositories {
    mavenCentral()
}

// Could also be set through gradle.properties file, than it looks like this
// spring-data-releasetrain.version=Lovelace-RELEASE
// neo4j-ogm.version=3.1.3

// Always set the complete release train, not the version of one specific spring data module
ext['spring-data-releasetrain.version'] = 'Lovelace-RELEASE'
// Overwrite the _managed_ version of OGM, otherwise you have to deal with manual imports in the dependencies
ext['neo4j-ogm.version'] = '3.1.3'

dependencies {
    compile('org.springframework.boot:spring-boot-starter-data-neo4j')

    // From Boot 2.0.6+ embedded driver will be managed as well,
    // for the time being, this is the official way to access Spring Boot
    // Managed properties in Gradle
    runtime("org.neo4j:neo4j-ogm-embedded-driver:${dependencyManagement.managedVersions['org.neo4j:neo4j-ogm-core']}")
    runtime("org.neo4j:neo4j:3.4.7")

    testCompile('org.springframework.boot:spring-boot-starter-test')
}

SettingReleaseTrainApplication.java

package com.example.settingreleasetrain;

import org.neo4j.ogm.annotation.NodeEntity;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.neo4j.repository.Neo4jRepository;

@NodeEntity
class ThingEntity {
    private Long id;

    private String name;

    public ThingEntity(String name) {
        this.name = name;
    }

    public Long getId() {
        return id;
    }

    public String getName() {
        return name;
    }
}

interface ThingRepository extends Neo4jRepository<ThingEntity, Long> {
}

@SpringBootApplication
public class SettingReleaseTrainApplication implements CommandLineRunner {

    private final ThingRepository thingRepository;

    public SettingReleaseTrainApplication(ThingRepository thingRepository) {
        this.thingRepository = thingRepository;
    }

    @Override
    public void run(String... args) throws Exception {
        ThingEntity thingEntity = thingRepository.save(new ThingEntity("A thing"));
        thingRepository.findById(thingEntity.getId()).ifPresent(aThing -> System.out.println(aThing.getName()));
    }

    public static void main(String[] args) {
        SpringApplication.run(SettingReleaseTrainApplication.class, args);
    }
}

Your problem can still be caused by a version incompatibility in the Spring components you are using. Could you post you build.gradle?