今天打包一个springboot的小demo 出现了一些问题
entityManagerFactory报错
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 java.lang.NoClassDefFoundError: javax/transaction/SystemException
这是自动配置entityManagerFactory组件出错 因为了解springboot自动配置,所以下意识的想去找自动配置
@Configuration
@ConditionalOnClass({ LocalContainerEntityManagerFactoryBean.class, EntityManager.class })
@Conditional(HibernateEntityManagerCondition.class)
@EnableConfigurationProperties(JpaProperties.class)
@AutoConfigureAfter({ DataSourceAutoConfiguration.class })
@Import(HibernateJpaConfiguration.class)
public class HibernateJpaAutoConfiguration {
找到了这个报错的东西 点进去看他报错的初始化方法
public HibernateJpaConfiguration(DataSource dataSource, JpaProperties jpaProperties,
ObjectProvider<JtaTransactionManager> jtaTransactionManager,
ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers,
ObjectProvider<Collection<DataSourcePoolMetadataProvider>> metadataProviders,
ObjectProvider<List<SchemaManagementProvider>> providers,
ObjectProvider<PhysicalNamingStrategy> physicalNamingStrategy,
ObjectProvider<ImplicitNamingStrategy> implicitNamingStrategy,
ObjectProvider<List<HibernatePropertiesCustomizer>> hibernatePropertiesCustomizers) {
super(dataSource, jpaProperties, jtaTransactionManager,
transactionManagerCustomizers);
this.defaultDdlAutoProvider = new HibernateDefaultDdlAutoProvider(
providers.getIfAvailable(Collections::emptyList));
this.poolMetadataProvider = new CompositeDataSourcePoolMetadataProvider(
metadataProviders.getIfAvailable());
this.physicalNamingStrategy = physicalNamingStrategy.getIfAvailable();
this.implicitNamingStrategy = implicitNamingStrategy.getIfAvailable();
this.hibernatePropertiesCustomizers = hibernatePropertiesCustomizers
.getIfAvailable(() -> Collections.emptyList());
}
既然来都来了就看一下怎么自动配置hibernate的把
查看父类JpaBaseConfiguration
@EnableConfigurationProperties(JpaProperties.class)
@Import(DataSourceInitializedPublisher.Registrar.class)
public abstract class JpaBaseConfiguration implements BeanFactoryAware {
重点也就上面两个注解@EnableConfigurationProperties 和@Import
@EnableConfigurationProperties(JpaProperties.class)点进去 就是一个绑定配置信息的类,把在配置文件中所有以spring.jpa配置前缀的绑定进来
@ConfigurationProperties(prefix = "spring.jpa")
public class JpaProperties {
@Import(DataSourceInitializedPublisher.Registrar.class)
registrar是DataSourceInitializedPublisher的一个内部类 很刺激,这类就是用来注册
DataSourceInitializedPublisher的
static class Registrar implements ImportBeanDefinitionRegistrar {
private static final String BEAN_NAME = "dataSourceInitializedPublisher";
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
BeanDefinitionRegistry registry) {
if (!registry.containsBeanDefinition(BEAN_NAME)) {
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClass(DataSourceInitializedPublisher.class);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
// We don't need this one to be post processed otherwise it can cause a
// cascade of bean instantiation that we would rather avoid.
beanDefinition.setSynthetic(true);
registry.registerBeanDefinition(BEAN_NAME, beanDefinition);
}
}
}
然后一直往父类或父接口往上查 发现最后实现的是 Aware接口,回过头发现问题还是尴尬的摆在那,于是动用通用的解决方法:检查pom依赖,检查plugin 删掉工程中test目录下的东西,删掉junit依赖 执行 mvn clean package打包成功
运行打包的jar报错
把上面的jar包拷出来 在命令行执行 java -jar 命令 出现spring boot启动页面
但是依旧报错
java.lang.NoClassDefFoundError:javax/xml/bind/JAXBException
java.lang.NoClassDefFoundError:javax/xml/bind/annotation/XmlType
一看到这个就笑了,以前见到过这个,这是少了javax相关jar包导致的
添加相关依赖解决
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.2.12</version>
</dependency>
然后去大佬的博客查找原因 大概是jdk版本引起的问题
我maven 执行的jdk 1.8版本 但是我系统配置的是 jdk 1.9
完美解决