springboot打包entityManagerFactory报错 以及运行jar出现的java.lang.NoClassDefFoundError:javax/xml/bind/JAXBExcep

今天打包一个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,
      ObjectProvider transactionManagerCustomizers,
      ObjectProvider> metadataProviders,
      ObjectProvider> providers,
      ObjectProvider physicalNamingStrategy,
      ObjectProvider implicitNamingStrategy,
      ObjectProvider> 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包导致的

添加相关依赖解决


    javax.xml.bind
    jaxb-api
    2.2.12

然后去大佬的博客查找原因 大概是jdk版本引起的问题

我maven 执行的jdk 1.8版本 但是我系统配置的是 jdk 1.9

完美解决

你可能感兴趣的:(踩过的坑)