创建名称为 'gemfireCache' 的 bean 时出错:FactoryBean 在创建对象时抛出异常
Error creating bean with name 'gemfireCache': FactoryBean threw exception on object creation
我正在尝试创建一个 "employee" 区域并将一些数据放入其中。但是,我在下面收到异常:
[warn 2018/12/27 17:15:46.518 IST tid=0x1] Exception
encountered during context initialization - cancelling refresh
attempt: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'gemfireConfiguration': Injection of
resource dependencies failed; nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'gemfireCache': FactoryBean threw exception on
object creation; nested exception is java.lang.NoClassDefFoundError:
it/unimi/dsi/fastutil/ints/Int2ObjectOpenHashMap
[warn 2018/12/27 17:15:46.519 IST tid=0x1] Invocation of
destroy method failed on bean with name 'gemfireCache':
org.apache.geode.cache.CacheClosedException: A cache has not yet been
created.
[error 2018/12/27 17:15:46.522 IST tid=0x1] Caught exception
while allowing TestExecutionListener
[org.springframework.test.context.web.ServletTestExecutionListener@c667f46]
to prepare test instance
[com.gemfire.demo.Gemfire1ApplicationTests@48bfb884]
域名class
@Region("employee")
public class Employee {
@Id
public String name;
public double salary;
...
}
存储库class
@Repository
public interface EmployeeRepository extends CrudRepository<Employee, String> {
Employee findByName(String name);
}
配置class
@Configuration
@ComponentScan
@EnableGemfireRepositories(basePackages = "com.gemfire.demo")
public class GemfireConfiguration {
@Autowired
EmployeeRepository employeeRepository;
@Bean
Properties gemfireProperties() {
Properties gemfireProperties = new Properties();
gemfireProperties.setProperty("name", "SpringDataGemFireApplication");
gemfireProperties.setProperty("mcast-port", "0");
gemfireProperties.setProperty("log-level", "config");
return gemfireProperties;
}
@Bean
@Autowired
CacheFactoryBean gemfireCache() {
CacheFactoryBean gemfireCache = new CacheFactoryBean();
gemfireCache.setClose(true);
gemfireCache.setProperties(gemfireProperties());
return gemfireCache;
}
@Bean(name="employee")
@Autowired
LocalRegionFactoryBean<String, Employee> getEmployee(final GemFireCache cache) {
LocalRegionFactoryBean<String, Employee> employeeRegion = new LocalRegionFactoryBean<String, Employee>();
employeeRegion.setCache(cache);
employeeRegion.setClose(false);
employeeRegion.setName("employee");
employeeRegion.setPersistent(false);
employeeRegion.setDataPolicy(DataPolicy.PRELOADED);
return employeeRegion;
}
}
POM.XML
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-to-slf4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-gemfire</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.9.0</version>
</dependency>
如评论中所述,错误显示缺少某些依赖项 (java.lang.NoClassDefFoundError: it/unimi/dsi/fastutil/ints/Int2ObjectOpenHashMap
)。请在你的pom.xml
中添加相应的依赖
在上面 GemFire/Spring JavaConfig 配置 class 中添加额外提示。
鉴于您正在使用 Spring Data Kay
(暗示您使用 Spring Boot 2.0.x
父 POM ,即 org.springframework.boot:spring-boot-dependencies
;参见 here), then you could be using Spring Data GemFire's (relatively) new and convenient Annotation-based configuration model。
这样,上面的 GemfireConfiguration
class 将变成...
@PeerCacheApplication
@EnableGemfireRepositories(basePackages = "com.gemfire.demo")
class GemfireConfiguration {
@Bean(name="employee")
LocalRegionFactoryBean<String, Employee> getEmployee(GemFireCache cache) {
LocalRegionFactoryBean<String, Employee> employeeRegion =
new LocalRegionFactoryBean<String, Employee>();
employeeRegion.setCache(cache);
employeeRegion.setClose(false);
employeeRegion.setDataPolicy(DataPolicy.PRELOADED);
return employeeRegion;
}
}
需要牢记的几点:
@PeerCacheApplication
使用 @Configuration
进行元注释,因此您不需要在配置 [=98= 上显式 Spring @Configuration
注释].
@PeerCacheApplication
允许您使用 logLevel
注释属性调整 GemFire 日志级别(以及其他日志记录配置)。同样,您可以在 Spring Boot application.properties
文件中使用相应的 属性、spring.data.gemfire.cache.log-level
设置日志级别(参见 here).还有许多其他属性和相应的属性(例如name
)可以用来调整和自定义其他配置。
虽然 @EnableGemfireRepositories
和类似注释支持基于字符串的包名称,但我们通常更喜欢并建议用户使用类型安全的变体 basePacakgeClasses
。您只需要从保存应用程序存储库的每个顶级包中引用一个类型。
您的 bean 定义不需要显式 @Autowired
注释。您不需要在配置 class 中显式注入 EmployeeRepository
来初始化它;只需将它注入 @Service
class 它将被使用的地方。
为方便起见,区域 bean 定义的名称 ("employee") 在您的本地 "employee" 区域中,也将用作区域的名称,因此 employeeRegion.setName("employee")
是不必要的。
您不应将 LocalRegionFactoryBean.setPersistent(:boolean)
与 LocalRegionFactoryBean.setDataPolicy(:DataPolicy)
结合使用,因为 DataPolicy 将优先。
虽然@ComponentScan
在开发中是完全可以接受甚至方便的,但我通常不喜欢也不推荐用户使用组件扫描。明确的通常总是更好。
如评论中所述,您应该从应用程序 Maven POM 文件中的父定义中删除 <relativePath/>
。
最后说明,截至目前 post,Spring Boot 2.0.8.RELEASE
是最新版本。
至于您的 class 路径问题,如果您正确使用 Maven,那么 Maven 应该负责引入正确的传递依赖项。
你可以参考我在这个 repo 中的许多例子来进一步说明。
希望对您有所帮助!
我正在尝试创建一个 "employee" 区域并将一些数据放入其中。但是,我在下面收到异常:
[warn 2018/12/27 17:15:46.518 IST tid=0x1] Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'gemfireConfiguration': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'gemfireCache': FactoryBean threw exception on object creation; nested exception is java.lang.NoClassDefFoundError: it/unimi/dsi/fastutil/ints/Int2ObjectOpenHashMap
[warn 2018/12/27 17:15:46.519 IST tid=0x1] Invocation of destroy method failed on bean with name 'gemfireCache': org.apache.geode.cache.CacheClosedException: A cache has not yet been created.
[error 2018/12/27 17:15:46.522 IST tid=0x1] Caught exception while allowing TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener@c667f46] to prepare test instance [com.gemfire.demo.Gemfire1ApplicationTests@48bfb884]
域名class
@Region("employee")
public class Employee {
@Id
public String name;
public double salary;
...
}
存储库class
@Repository
public interface EmployeeRepository extends CrudRepository<Employee, String> {
Employee findByName(String name);
}
配置class
@Configuration
@ComponentScan
@EnableGemfireRepositories(basePackages = "com.gemfire.demo")
public class GemfireConfiguration {
@Autowired
EmployeeRepository employeeRepository;
@Bean
Properties gemfireProperties() {
Properties gemfireProperties = new Properties();
gemfireProperties.setProperty("name", "SpringDataGemFireApplication");
gemfireProperties.setProperty("mcast-port", "0");
gemfireProperties.setProperty("log-level", "config");
return gemfireProperties;
}
@Bean
@Autowired
CacheFactoryBean gemfireCache() {
CacheFactoryBean gemfireCache = new CacheFactoryBean();
gemfireCache.setClose(true);
gemfireCache.setProperties(gemfireProperties());
return gemfireCache;
}
@Bean(name="employee")
@Autowired
LocalRegionFactoryBean<String, Employee> getEmployee(final GemFireCache cache) {
LocalRegionFactoryBean<String, Employee> employeeRegion = new LocalRegionFactoryBean<String, Employee>();
employeeRegion.setCache(cache);
employeeRegion.setClose(false);
employeeRegion.setName("employee");
employeeRegion.setPersistent(false);
employeeRegion.setDataPolicy(DataPolicy.PRELOADED);
return employeeRegion;
}
}
POM.XML
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-to-slf4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-gemfire</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.9.0</version>
</dependency>
如评论中所述,错误显示缺少某些依赖项 (java.lang.NoClassDefFoundError: it/unimi/dsi/fastutil/ints/Int2ObjectOpenHashMap
)。请在你的pom.xml
在上面 GemFire/Spring JavaConfig 配置 class 中添加额外提示。
鉴于您正在使用 Spring Data Kay
(暗示您使用 Spring Boot 2.0.x
父 POM ,即 org.springframework.boot:spring-boot-dependencies
;参见 here), then you could be using Spring Data GemFire's (relatively) new and convenient Annotation-based configuration model。
这样,上面的 GemfireConfiguration
class 将变成...
@PeerCacheApplication
@EnableGemfireRepositories(basePackages = "com.gemfire.demo")
class GemfireConfiguration {
@Bean(name="employee")
LocalRegionFactoryBean<String, Employee> getEmployee(GemFireCache cache) {
LocalRegionFactoryBean<String, Employee> employeeRegion =
new LocalRegionFactoryBean<String, Employee>();
employeeRegion.setCache(cache);
employeeRegion.setClose(false);
employeeRegion.setDataPolicy(DataPolicy.PRELOADED);
return employeeRegion;
}
}
需要牢记的几点:
@PeerCacheApplication
使用@Configuration
进行元注释,因此您不需要在配置 [=98= 上显式 Spring@Configuration
注释].@PeerCacheApplication
允许您使用logLevel
注释属性调整 GemFire 日志级别(以及其他日志记录配置)。同样,您可以在 Spring Bootapplication.properties
文件中使用相应的 属性、spring.data.gemfire.cache.log-level
设置日志级别(参见 here).还有许多其他属性和相应的属性(例如name
)可以用来调整和自定义其他配置。虽然
@EnableGemfireRepositories
和类似注释支持基于字符串的包名称,但我们通常更喜欢并建议用户使用类型安全的变体basePacakgeClasses
。您只需要从保存应用程序存储库的每个顶级包中引用一个类型。您的 bean 定义不需要显式
@Autowired
注释。您不需要在配置 class 中显式注入EmployeeRepository
来初始化它;只需将它注入@Service
class 它将被使用的地方。为方便起见,区域 bean 定义的名称 ("employee") 在您的本地 "employee" 区域中,也将用作区域的名称,因此
employeeRegion.setName("employee")
是不必要的。您不应将
LocalRegionFactoryBean.setPersistent(:boolean)
与LocalRegionFactoryBean.setDataPolicy(:DataPolicy)
结合使用,因为 DataPolicy 将优先。虽然
@ComponentScan
在开发中是完全可以接受甚至方便的,但我通常不喜欢也不推荐用户使用组件扫描。明确的通常总是更好。如评论中所述,您应该从应用程序 Maven POM 文件中的父定义中删除
<relativePath/>
。最后说明,截至目前 post,Spring Boot
2.0.8.RELEASE
是最新版本。
至于您的 class 路径问题,如果您正确使用 Maven,那么 Maven 应该负责引入正确的传递依赖项。
你可以参考我在这个 repo 中的许多例子来进一步说明。
希望对您有所帮助!