Marcin Kłopotek
Marcin Kłopotek

Reputation: 5931

Spring Data Rest and spring-data-rest-hal-browser integration using Spring Boot

Problem

The Spring Data REST Reference Documentation says that

dependencies {
    compile 'org.springframework.data:spring-data-rest-hal-browser'
}

is enough to integrate HAL browser with Spring Data Rest while using Spring Boot but Gradle complains this dependency cannot be found unless I specify particular version so I fixed it by specifying the latest one available in central repository (there is no other version available in the repository). After specifying the version the dependency is resolved but I get an error during Spring Boot container initialization:

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.repository.support.Repositories]: Factory method 'repositories' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cameraRepository': Invocation of init method failed; nested exception is java.lang.AbstractMethodError: org.springframework.data.repository.core.support.RepositoryFactorySupport.getTargetRepository(Lorg/springframework/data/repository/core/RepositoryInformation;)Ljava/lang/Object;
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588)
    ... 151 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cameraRepository': Invocation of init method failed; nested exception is java.lang.AbstractMethodError: org.springframework.data.repository.core.support.RepositoryFactorySupport.getTargetRepository(Lorg/springframework/data/repository/core/RepositoryInformation;)Ljava/lang/Object;
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1572)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:966)
    at org.springframework.data.repository.support.Repositories.cacheRepositoryFactory(Repositories.java:95)
    at org.springframework.data.repository.support.Repositories.populateRepositoryFactoryInformation(Repositories.java:88)
    at org.springframework.data.repository.support.Repositories.<init>(Repositories.java:81)
    at org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration.repositories(RepositoryRestMvcConfiguration.java:182)
    at org.springframework.boot.autoconfigure.data.rest.SpringBootRepositoryRestMvcConfiguration$$EnhancerBySpringCGLIB$$b6ea42c0.CGLIB$repositories$11(<generated>)
    at org.springframework.boot.autoconfigure.data.rest.SpringBootRepositoryRestMvcConfiguration$$EnhancerBySpringCGLIB$$b6ea42c0$$FastClassBySpringCGLIB$$ec6a4119.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:309)
    at org.springframework.boot.autoconfigure.data.rest.SpringBootRepositoryRestMvcConfiguration$$EnhancerBySpringCGLIB$$b6ea42c0.repositories(<generated>)
    at sun.reflect.NativeMetssorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
    ... 152 more
Caused by: java.lang.AbstractMethodError: org.springframework.data.repository.core.support.RepositoryFactorySupport.getTargetRepository(Lorg/springframework/data/repository/core/RepositoryInformation;)Ljava/lang/Object;
    at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:185)
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:251)
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:237)
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:92)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1631)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1568)
    ... 173 more

However my application initializes successfully and works as expected if I remove spring-data-rest-hal-browser:2.4.0.RELEASE dependency.

Question

How can I setup my build.gradle correctly to have my application integrated with HAL browser properly?


build.gradle

buildscript {
    ext {
        springBootVersion = '1.2.7.RELEASE'
    }

    repositories {
        mavenCentral()
    }
}

dependencies {
    classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    classpath('io.spring.gradle:dependency-management-plugin:0.5.2.RELEASE')
}

[...]

repositories {
    mavenCentral()
    flatDir {
       dirs 'lib'
    }
}

dependencies {
    compile('org.springframework.boot:spring-boot-starter-actuator')
    compile('org.springframework.boot:spring-boot-starter-data-jpa')
    compile('org.springframework.boot:spring-boot-starter-data-rest')
    compile('org.springframework.boot:spring-boot-starter-remote-shell')
    compile('org.springframework.data:spring-data-rest-hal-browser:2.4.0.RELEASE')
    compile('org.projectlombok:lombok:1.16.6')
    compile name: 'ojdbc6'
    testCompile('org.springframework.boot:spring-boot-starter-test')
    testCompile('org.springframework.restdocs:spring-restdocs-mockmvc:1.0.0.RELEASE')
}

Upvotes: 3

Views: 3771

Answers (2)

naXa stands with Ukraine
naXa stands with Ukraine

Reputation: 37936

The package was renamed to spring-data-rest-hal-explorer. Here's an example of a modern configuration of HAL with Spring Boot 2 with automatic version management.

Maven example:

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-rest-hal-explorer</artifactId>
</dependency>

Gradle example:

plugins {
    id "io.spring.dependency-management" version <<version>>
}

dependencies {
    implementation('org.springframework.data:spring-data-rest-hal-explorer')
}

Upvotes: 0

nerdherd
nerdherd

Reputation: 2603

The automatic version management for the HAL browser only works starting with Spring Boot 1.3.0 which is at the release candidate stage and should be released very soon. The release candidate is very stable for me, so you may consider giving that a try by updating your build to 1.3.0.RC1 which I would expect would fix the issue, something like this:

buildscript {
    ext {
        springBootVersion = '1.3.0.RC1'
    }
    repositories {
        mavenCentral()
        maven { url 'https://repo.spring.io/milestone/' }
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
        classpath "io.spring.gradle:dependency-management-plugin:0.5.2.RELEASE"
    }
}

repositories {
    mavenCentral()
    flatDir {
       dirs 'lib'
    }
}

dependencies {
    compile('org.springframework.boot:spring-boot-starter-actuator')
    compile('org.springframework.boot:spring-boot-starter-data-jpa')
    compile('org.springframework.boot:spring-boot-starter-data-rest')
    compile('org.springframework.boot:spring-boot-starter-remote-shell')
    compile('org.springframework.data:spring-data-rest-hal-browser')
    compile('org.projectlombok:lombok:1.16.6')
    compile name: 'ojdbc6'
    testCompile('org.springframework.boot:spring-boot-starter-test')
    testCompile('org.springframework.restdocs:spring-restdocs-mockmvc')
}

You can see the managed dependency versions for 1.3.0.RC1 here:

http://docs.spring.io/spring-boot/docs/1.3.0.RC1/reference/htmlsingle/#appendix-dependency-versions

You'll notice if you look at the managed dependency versions for 1.2.7 that neither spring-data-rest-hal-browser nor spring-restdocs-mockmvc are present.

Upvotes: 2

Related Questions