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.