the Spring CLI not work well with spring-data-jpa
I write a demo, name it 1.groovy
package org.goodjob.demo
@Grab("spring-boot-starter-data-jpa")
@Grab("h2")
import javax.persistence.*
// import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.repository.CrudRepository
import org.springframework.data.jpa.repository.config.EnableJpaRepositories
@Configuration
@EnableAutoConfiguration
@ComponentScan("org.goodjob")
@EnableJpaRepositories("org.goodjob")
class MyConfig {}
@RestController
class Demo {
@Autowired
CustomerRepository customerRepo
@RequestMapping("/")
String home() {
"hello world!"
}
}
interface CustomerRepository extends CrudRepository<Customer, Long> {
List<Customer> findByName(String name)
}
@Entity
class Customer {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
Long id
String name
Integer age
}
$ spring version
Spring CLI v2.1.2.RELEASE
spring run 1.groovy
***************************
APPLICATION FAILED TO START
***************************
Description:
Field customerRepo in Demo required a bean of type 'CustomerRepository' that could not be found.
The injection point has the following annotations:
- @org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'CustomerRepository' in your configuration.
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.boot.cli.app.SpringApplicationLauncher.launch(SpringApplicationLauncher.java:69)
at org.springframework.boot.cli.command.run.SpringApplicationRunner$RunThread.run(SpringApplicationRunner.java:173)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'demo': Unsatisfied dependency expressed through field 'customerRepo'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'CustomerRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
...
Comment From: wilkinsona
Thanks for the report. The problem is due to a limitation of the CLI's ExtendedGroovyClassLoader.
ExtendedGroovyClassLoader keeps track of the resources for classes that have been compiled from Groovy source code in its classResources map but then only uses that map in getResourceAsStream. The map is not considered when a call to findResources is made. In your example findResources is called with org/goodjob/demo/. A URL needs to be returned that will then allow Spring Framework's resource pattern resolver to find the classes in the org.goodjob.demo package.
You can work around the problem by compiling your CLI application and then running it as a jar file:
spring jar app.jar 1.groovy
java -jar app.jar
Comment From: wilkinsona
Support for running and building apps using the CLI was removed in Spring Boot 3.0.