我有一个 Spring Boot Camel 项目,它使用 Hibernate 并启用了它的 L2 缓存系统。我使用的 L2 缓存提供程序是 Redis,应用程序通过 Spring Redission starter 连接。
我通过maven(基本上是一个FAT jar)打包应用程序,并且要求我必须独立运行应用程序。我已将与应用程序相关的所有属性文件(包括 application.properties 文件)放在配置文件夹中。
我希望从胖 jar 中取出所有属性文件的原因是我希望属性的值是可配置的,而不是我必须经常构建一个 jar 文件来进行较小的配置更改。
我通过 Eclipse 通过 maven 项目的运行配置中的 maven 安装选项使用 maven 的maven-jar-plugin构建 jar 。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3</version>
<configuration>
<excludes>
<exclude>**/*.properties</exclude>
<exclude>**/*.json</exclude>
<exclude>**/*.xml</exclude>
</excludes>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.elstacker.main</mainClass>
</manifest>
<!-- <manifestEntries>
<Class-Path>conf/</Class-Path>
</manifestEntries> -->
</archive>
</configuration>
</plugin>
我也试过评论上面的插件,只是使用资源标签/坐标来排除 .jar 文件中不需要的文件。
<resources>
<resource>
<directory>src/main/resources</directory>
<excludes>
<exclude>*.properties</exclude>
<exclude>*.json</exclude>
<exclude>*.xml</exclude>
</excludes>
<filtering>true</filtering>
</resource>
</resources>
独立应用程序服务器布局如下所示:
项目布局1
项目布局2
由于应用程序还涉及访问 Redis 服务器以获取休眠 L2 缓存,因此application.properties文件中提到的休眠相关属性条目很少。L2 Cache 配置片段如下:
spring.jpa.properties.hibernate.cache.auto_evict_collection_cache=false
spring.jpa.properties.hibernate.generate_statistics=false
spring.jpa.properties.hibernate.cache.use_second_level_cache=true
spring.jpa.properties.hibernate.cache.use_query_cache=true
spring.jpa.properties.hibernate.javax.cache.missing_cache_strategy=create
spring.jpa.properties.cache.region.factory_class=com.redis.RedissionConfig
spring.jpa.properties.javax.persistence.sharedCache.mode=ENABLE_SELECTIVE
我会使用自定义 RedissionConfigFactory 在应用程序启动期间启动 redis 连接管理器。代码如下所示:
public class RedissionConfig extends org.redisson.hibernate.RedissonRegionFactory{
private static final long serialVersionUID = 1L;
Logger log = LogManager.getLogger("com.fss.convertor");
@Bean
public RedissonConnectionFactory redissonConnectionFactory(RedissonClient redisson) {
return new RedissonConnectionFactory(redisson);
}
@Bean(destroyMethod = "shutdown")
public RedissonClient redisson() throws IOException {
return Redisson.create(buildConfigFile());
}
public Config buildConfigFile() {
//Resource resource = null;
//InputStream input = null;
Config config = null;
File file=null;
try {
//resource = new ClassPathResource("redisson.json");
//input = resource.getInputStream();
//File file = resource.getFile();
ClassPathResource path = new ClassPathResource("redisson.json");
log.info("path ::: "+path.getPath());
file = new File(path.getPath());
log.info("file :::"+ file.exists() +":::" + file.getAbsolutePath());
config = Config.fromJSON(file);
}catch(Exception e) {
log.info("Exception ::: "+e.getMessage());
}finally {}
return config;
}
@Bean
CacheManager cacheManager(RedissonClient redissonClient) {
Map<String, CacheConfig> config = new HashMap<>();
CacheConfig configItem = new CacheConfig(TimeUnit.MINUTES.toMillis(60), TimeUnit.MINUTES.toMillis(30));
config.put("domainCache",configItem);
return new RedissonSpringCacheManager(redissonClient, config);
}
}
当我使用 Eclipse 时,该应用程序启动并正常工作。但是当我通过 maven 打包应用程序后尝试将应用程序作为独立应用程序启动时,应用程序无法加载自定义 RedisConfigFactory 类文件,因为该文件现在位于 .jar 文件中,我觉得 hibernate 是找不到属性 spring.jpa.properties.cache.region.factory_class=com.redis.RedissionConfig中提到的类文件
我留下了一个例外,如下所述:
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2019-09-24 17:10:52.559 [ERROR] [SpringApplication.java:821] - Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.cache.spi.CacheImplementor]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1778) ~[spring-beans-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:593) ~[spring-beans-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) ~[spring-beans-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) ~[spring-beans-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) ~[spring-beans-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1105) ~[spring-context-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867) ~[spring-context-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549) ~[spring-context-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140) ~[spring-boot-2.1.6.RELEASE.jar!/:2.1.6.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:742) [spring-boot-2.1.6.RELEASE.jar!/:2.1.6.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:389) [spring-boot-2.1.6.RELEASE.jar!/:2.1.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:311) [spring-boot-2.1.6.RELEASE.jar!/:2.1.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1213) [spring-boot-2.1.6.RELEASE.jar!/:2.1.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1202) [spring-boot-2.1.6.RELEASE.jar!/:2.1.6.RELEASE]
at com.messageconvertorstarter.MessageConvertorStarter.main(MessageConvertorStarter.java:41) [classes!/:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_171]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_171]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_171]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_171]
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:47) [MessageConvertor-0.0.2.jar:?]
at org.springframework.boot.loader.Launcher.launch(Launcher.java:86) [MessageConvertor-0.0.2.jar:?]
at org.springframework.boot.loader.Launcher.launch(Launcher.java:50) [MessageConvertor-0.0.2.jar:?]
at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51) [MessageConvertor-0.0.2.jar:?]
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.cache.spi.CacheImplementor]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:402) ~[spring-orm-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:377) ~[spring-orm-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341) ~[spring-orm-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1837) ~[spring-beans-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1774) ~[spring-beans-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]
... 24 more
Caused by: org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.cache.spi.CacheImplementor]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:275) ~[hibernate-core-5.3.10.Final.jar!/:5.3.10.Final]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:237) ~[hibernate-core-5.3.10.Final.jar!/:5.3.10.Final]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214) ~[hibernate-core-5.3.10.Final.jar!/:5.3.10.Final]
at org.hibernate.service.internal.SessionFactoryServiceRegistryImpl.getService(SessionFactoryServiceRegistryImpl.java:109) ~[hibernate-core-5.3.10.Final.jar!/:5.3.10.Final]
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:239) ~[hibernate-core-5.3.10.Final.jar!/:5.3.10.Final]
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:467) ~[hibernate-core-5.3.10.Final.jar!/:5.3.10.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:939) ~[hibernate-core-5.3.10.Final.jar!/:5.3.10.Final]
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:57) ~[spring-orm-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) ~[spring-orm-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:390) ~[spring-orm-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:377) ~[spring-orm-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341) ~[spring-orm-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1837) ~[spring-beans-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1774) ~[spring-beans-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]
... 24 more
Caused by: java.lang.IllegalStateException: Cache provider not started
at org.hibernate.cache.spi.AbstractRegionFactory.verifyStarted(AbstractRegionFactory.java:65) ~[hibernate-core-5.3.10.Final.jar!/:5.3.10.Final]
at org.hibernate.cache.spi.support.RegionFactoryTemplate.buildTimestampsRegion(RegionFactoryTemplate.java:66) ~[hibernate-core-5.3.10.Final.jar!/:5.3.10.Final]
at org.hibernate.cache.internal.EnabledCaching.<init>(EnabledCaching.java:80) ~[hibernate-core-5.3.10.Final.jar!/:5.3.10.Final]
at org.hibernate.engine.spi.CacheInitiator.initiateService(CacheInitiator.java:33) ~[hibernate-core-5.3.10.Final.jar!/:5.3.10.Final]
at org.hibernate.engine.spi.CacheInitiator.initiateService(CacheInitiator.java:24) ~[hibernate-core-5.3.10.Final.jar!/:5.3.10.Final]
at org.hibernate.service.spi.SessionFactoryServiceInitiator.initiateService(SessionFactoryServiceInitiator.java:30) ~[hibernate-core-5.3.10.Final.jar!/:5.3.10.Final]
at org.hibernate.service.internal.SessionFactoryServiceRegistryImpl.initiateService(SessionFactoryServiceRegistryImpl.java:68) ~[hibernate-core-5.3.10.Final.jar!/:5.3.10.Final]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263) ~[hibernate-core-5.3.10.Final.jar!/:5.3.10.Final]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:237) ~[hibernate-core-5.3.10.Final.jar!/:5.3.10.Final]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214) ~[hibernate-core-5.3.10.Final.jar!/:5.3.10.Final]
at org.hibernate.service.internal.SessionFactoryServiceRegistryImpl.getService(SessionFactoryServiceRegistryImpl.java:109) ~[hibernate-core-5.3.10.Final.jar!/:5.3.10.Final]
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:239) ~[hibernate-core-5.3.10.Final.jar!/:5.3.10.Final]
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:467) ~[hibernate-core-5.3.10.Final.jar!/:5.3.10.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:939) ~[hibernate-core-5.3.10.Final.jar!/:5.3.10.Final]
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:57) ~[spring-orm-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) ~[spring-orm-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:390) ~[spring-orm-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:377) ~[spring-orm-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341) ~[spring-orm-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1837) ~[spring-beans-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1774) ~[spring-beans-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]
... 24 more
Caused by: org.hibernate.cache.CacheException: Unable to locate Redisson configuration
at org.redisson.hibernate.RedissonRegionFactory.createRedissonClient(RedissonRegionFactory.java:97) ~[redisson-hibernate-53-3.10.0.jar!/:?]
at org.redisson.hibernate.RedissonRegionFactory.prepareForUse(RedissonRegionFactory.java:78) ~[redisson-hibernate-53-3.10.0.jar!/:?]
at org.hibernate.cache.spi.AbstractRegionFactory.start(AbstractRegionFactory.java:91) ~[hibernate-core-5.3.10.Final.jar!/:5.3.10.Final]
at org.hibernate.cache.internal.EnabledCaching.<init>(EnabledCaching.java:77) ~[hibernate-core-5.3.10.Final.jar!/:5.3.10.Final]
at org.hibernate.engine.spi.CacheInitiator.initiateService(CacheInitiator.java:33) ~[hibernate-core-5.3.10.Final.jar!/:5.3.10.Final]
at org.hibernate.engine.spi.CacheInitiator.initiateService(CacheInitiator.java:24) ~[hibernate-core-5.3.10.Final.jar!/:5.3.10.Final]
at org.hibernate.service.spi.SessionFactoryServiceInitiator.initiateService(SessionFactoryServiceInitiator.java:30) ~[hibernate-core-5.3.10.Final.jar!/:5.3.10.Final]
at org.hibernate.service.internal.SessionFactoryServiceRegistryImpl.initiateService(SessionFactoryServiceRegistryImpl.java:68) ~[hibernate-core-5.3.10.Final.jar!/:5.3.10.Final]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263) ~[hibernate-core-5.3.10.Final.jar!/:5.3.10.Final]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:237) ~[hibernate-core-5.3.10.Final.jar!/:5.3.10.Final]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214) ~[hibernate-core-5.3.10.Final.jar!/:5.3.10.Final]
at org.hibernate.service.internal.SessionFactoryServiceRegistryImpl.getService(SessionFactoryServiceRegistryImpl.java:109) ~[hibernate-core-5.3.10.Final.jar!/:5.3.10.Final]
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:239) ~[hibernate-core-5.3.10.Final.jar!/:5.3.10.Final]
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:467) ~[hibernate-core-5.3.10.Final.jar!/:5.3.10.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:939) ~[hibernate-core-5.3.10.Final.jar!/:5.3.10.Final]
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:57) ~[spring-orm-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) ~[spring-orm-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:390) ~[spring-orm-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:377) ~[spring-orm-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341) ~[spring-orm-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1837) ~[spring-beans-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1774) ~[spring-beans-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]
... 24 more
我还尝试了通过替换spring.jpa.properties.cache.region.factory_class=com.redis.RedissionConfig来注入类文件的其他方法
如下所示:
- (如果类可能已经被spring注入到休眠类加载器)
- spring.jpa.properties.cache.region.factory_class=#redissionConfig以及
- spring.jpa.properties.cache.region.factory_class=${redissionConfig}
但是,它仍然没有用。我面临与上述相同的异常。
任何人都可以帮我解决如何从spring boot的application.properties文件中加载/引用位于.jar文件中的类文件,该文件位于其实际包结构之外。
任何帮助都将不胜感激,因为我被困在这里不知道如何解决这个问题。