Docker中的SpringBoot + Postgres:在docker-compose上:无法初始化JPA EntityManagerFactory:无法加载类

Posted

技术标签:

【中文标题】Docker中的SpringBoot + Postgres:在docker-compose上:无法初始化JPA EntityManagerFactory:无法加载类【英文标题】:SpringBoot+Postgres in Docker: on docker-compose: Failed to initialize JPA EntityManagerFactory: Unable to load class 【发布时间】:2021-10-16 02:21:28 【问题描述】:

我有一些使用 Spring Boot 和 Postgres 用 Ja​​va 编写的后端应用程序。

如果我从 Intelliji 在本地运行该应用程序,它可以完美运行,但是当我编译为 jar 并运行 docker build --no-cache -t application.jar .docker-compose up 时,后端崩溃。 postgres 容器似乎工作正常,但 spring boot 容器失败并显示以下内容:

spring_boot_back_end    | 2021-08-12 17:14:09.935  INFO 1 --- [           main] e.e.t.c.SomeApplication           : Starting Application using Java 11.0.12 on 5fa243e643ca with PID 1 (/application.jar started by root in /)
spring_boot_back_end    | 2021-08-12 17:14:09.938  INFO 1 --- [           main] e.e.t.c.SomeApplication           : No active profile set, falling back to default profiles: default
spring_boot_back_end    | 2021-08-12 17:14:10.618  INFO 1 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
spring_boot_back_end    | 2021-08-12 17:14:10.666  INFO 1 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 41 ms. Found 4 JPA repository interfaces.
spring_boot_back_end    | 2021-08-12 17:14:11.134  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
spring_boot_back_end    | 2021-08-12 17:14:11.146  INFO 1 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
spring_boot_back_end    | 2021-08-12 17:14:11.146  INFO 1 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.50]
spring_boot_back_end    | 2021-08-12 17:14:11.194  INFO 1 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
spring_boot_back_end    | 2021-08-12 17:14:11.194  INFO 1 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1213 ms
spring_boot_back_end    | 2021-08-12 17:14:11.304  INFO 1 --- [           main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
spring_boot_back_end    | 2021-08-12 17:14:11.340  INFO 1 --- [           main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.0.0.Alpha9
spring_boot_back_end    | 2021-08-12 17:14:11.461  INFO 1 --- [           main] o.hibernate.annotations.common.Version   : HCANN000001: Hibernate Commons Annotations 5.1.2.Final
spring_boot_back_end    | 2021-08-12 17:14:11.556  INFO 1 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
spring_boot_back_end    | 2021-08-12 17:14:11.615  INFO 1 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
spring_boot_back_end    | 2021-08-12 17:14:11.630  INFO 1 --- [           main] SQL dialect                              : HHH000400: Using dialect: org.hibernate.dialect.PostgreSQLDialect
spring_boot_back_end    | 2021-08-12 17:14:11.669 ERROR 1 --- [           main] j.LocalContainerEntityManagerFactoryBean : Failed to initialize JPA EntityManagerFactory: Unable to load class [...model.something.Something]
spring_boot_back_end    | 2021-08-12 17:14:11.670  WARN 1 --- [           main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: 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 org.hibernate.boot.registry.classloading.spi.ClassLoadingException: Unable to load class [...model.something.Something]
spring_boot_back_end    | 2021-08-12 17:14:11.670  INFO 1 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
spring_boot_back_end    | 2021-08-12 17:14:11.672  INFO 1 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
spring_boot_back_end    | 2021-08-12 17:14:11.674  INFO 1 --- [           main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
spring_boot_back_end    | 2021-08-12 17:14:11.682  INFO 1 --- [           main] ConditionEvaluationReportLoggingListener :
spring_boot_back_end    |
spring_boot_back_end    | Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
spring_boot_back_end    | 2021-08-12 17:14:11.694 ERROR 1 --- [           main] o.s.boot.SpringApplication               : Application run failed
spring_boot_back_end    |
spring_boot_back_end    | 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 org.hibernate.boot.registry.classloading.spi.ClassLoadingException: Unable to load class [...model.something.Something]
spring_boot_back_end    |       at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1786) ~[spring-beans-5.3.9.jar!/:5.3.9]
spring_boot_back_end    |       at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:602) ~[spring-beans-5.3.9.jar!/:5.3.9]
spring_boot_back_end    |       at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524) ~[spring-beans-5.3.9.jar!/:5.3.9]
spring_boot_back_end    |       at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.9.jar!/:5.3.9]
spring_boot_back_end    |       at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.9.jar!/:5.3.9]
spring_boot_back_end    |       at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.9.jar!/:5.3.9]
spring_boot_back_end    |       at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.9.jar!/:5.3.9]
spring_boot_back_end    |       at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:908) ~[spring-context-5.3.9.jar!/:5.3.9]
spring_boot_back_end    |       at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.9.jar!/:5.3.9]
spring_boot_back_end    |       at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145) ~[spring-boot-2.5.3.jar!/:2.5.3]
spring_boot_back_end    |       at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) ~[spring-boot-2.5.3.jar!/:2.5.3]
spring_boot_back_end    |       at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:434) ~[spring-boot-2.5.3.jar!/:2.5.3]
spring_boot_back_end    |       at org.springframework.boot.SpringApplication.run(SpringApplication.java:338) ~[spring-boot-2.5.3.jar!/:2.5.3]
spring_boot_back_end    |       at org.springframework.boot.SpringApplication.run(SpringApplication.java:1343) ~[spring-boot-2.5.3.jar!/:2.5.3]
spring_boot_back_end    |       at org.springframework.boot.SpringApplication.run(SpringApplication.java:1332) ~[spring-boot-2.5.3.jar!/:2.5.3]
spring_boot_back_end    |       at ...SomeApplication.main(SomeApplication.java:10) ~[classes!/:na]
spring_boot_back_end    |       at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
spring_boot_back_end    |       at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
spring_boot_back_end    |       at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
spring_boot_back_end    |       at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
spring_boot_back_end    |       at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49) ~[charity-sale.jar:na]
spring_boot_back_end    |       at org.springframework.boot.loader.Launcher.launch(Launcher.java:108) ~[charity-sale.jar:na]
spring_boot_back_end    |       at org.springframework.boot.loader.Launcher.launch(Launcher.java:58) ~[charity-sale.jar:na]
spring_boot_back_end    |       at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:88) ~[charity-sale.jar:na]
spring_boot_back_end    | Caused by: org.hibernate.boot.registry.classloading.spi.ClassLoadingException: Unable to load class [...model.something.Something]
spring_boot_back_end    |       at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.classForName(ClassLoaderServiceImpl.java:136) ~[hibernate-core-6.0.0.Alpha9.jar!/:6.0.0.Alpha9]
spring_boot_back_end    |       at org.hibernate.boot.model.source.internal.annotations.AnnotationMetadataSourceProcessorImpl.<init>(AnnotationMetadataSourceProcessorImpl.java:101) ~[hibernate-core-6.0.0.Alpha9.jar!/:6.0.0.Alpha9]
spring_boot_back_end    |       at org.hibernate.boot.model.process.spi.MetadataBuildingProcess$1.<init>(MetadataBuildingProcess.java:163) ~[hibernate-core-6.0.0.Alpha9.jar!/:6.0.0.Alpha9]
spring_boot_back_end    |       at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:157) ~[hibernate-core-6.0.0.Alpha9.jar!/:6.0.0.Alpha9]
spring_boot_back_end    |       at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1345) ~[hibernate-core-6.0.0.Alpha9.jar!/:6.0.0.Alpha9]
spring_boot_back_end    |       at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1416) ~[hibernate-core-6.0.0.Alpha9.jar!/:6.0.0.Alpha9]
spring_boot_back_end    |       at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58) ~[spring-orm-5.3.9.jar!/:5.3.9]
spring_boot_back_end    |       at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) ~[spring-orm-5.3.9.jar!/:5.3.9]
spring_boot_back_end    |       at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409) ~[spring-orm-5.3.9.jar!/:5.3.9]
spring_boot_back_end    |       at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396) ~[spring-orm-5.3.9.jar!/:5.3.9]
spring_boot_back_end    |       at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341) ~[spring-orm-5.3.9.jar!/:5.3.9]
spring_boot_back_end    |       at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1845) ~[spring-beans-5.3.9.jar!/:5.3.9]
spring_boot_back_end    |       at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1782) ~[spring-beans-5.3.9.jar!/:5.3.9]
spring_boot_back_end    |       ... 24 common frames omitted
spring_boot_back_end    | Caused by: java.lang.NoClassDefFoundError: org/springframework/boot/configurationprocessor/json/JSONException
spring_boot_back_end    |       at java.base/java.lang.Class.forName0(Native Method) ~[na:na]
spring_boot_back_end    |       at java.base/java.lang.Class.forName(Class.java:398) ~[na:na]
spring_boot_back_end    |       at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.classForName(ClassLoaderServiceImpl.java:130) ~[hibernate-core-6.0.0.Alpha9.jar!/:6.0.0.Alpha9]
spring_boot_back_end    |       ... 36 common frames omitted
spring_boot_back_end    | Caused by: java.lang.ClassNotFoundException: org.springframework.boot.configurationprocessor.json.JSONException
spring_boot_back_end    |       at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:471) ~[na:na]
spring_boot_back_end    |       at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:589) ~[na:na]
spring_boot_back_end    |       at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:151) ~[charity-sale.jar:na]
spring_boot_back_end    |       at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522) ~[na:na]
spring_boot_back_end    |       ... 39 common frames omitted
spring_boot_back_end    |
spring_boot_back_end exited with code 1

我的Dockerfile

FROM openjdk:11
COPY ./build/libs/application.jar application.jar
ENTRYPOINT ["java", "-jar", "application.jar"]
EXPOSE 8080

我的docker-compose.yml

version: "3"
services:
  spring_boot_back_end:
    build: .
    container_name: spring_boot_back_end
    environment:
      SPRING_DATASOURCE_URL: jdbc:postgresql://postgres_db:5432/postgres
    ports:
      - "8080:8080"
    restart: "no"
    depends_on:
      - postgres_db
  postgres_db:
    image: postgres
    container_name: postgres_db
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=postgres
      - PGDATA=/var/lib/postgresql/data/pgdata
    ports:
      - "5432:5432"
    volumes:
      - pgdata:/var/lib/postgresql/data
    restart: "no"
volumes:
  pgdata:

我的build.gradle

plugins 
    id 'org.springframework.boot' version '2.5.3'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'java'


group = 'some.group'
version = 'v0.1'
sourceCompatibility = '11'

bootJar 
    archiveFileName = 'application.jar'


configurations 
    compileOnly 
        extendsFrom annotationProcessor
    


repositories 
    mavenCentral()


dependencies 
    annotationProcessor 'org.projectlombok:lombok'
    annotationProcessor group: 'org.springframework.boot', name: 'spring-boot-configuration-processor', version: '2.5.3'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.session:spring-session-core'
    implementation 'org.springframework.boot:spring-boot-starter-validation'
    implementation group: 'io.springfox', name: 'springfox-boot-starter', version: '3.0.0'
    implementation 'org.hibernate.orm:hibernate-core:6.0.0.Alpha9'
    implementation 'org.hibernate.javax.persistence:hibernate-jpa-2.1-api:1.0.2.Final'
    compileOnly 'org.projectlombok:lombok'
    runtimeOnly 'org.postgresql:postgresql'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'


test 
    useJUnitPlatform()


我的application.properties

spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
spring.datasource.username=postgres
spring.datasource.password=password
#spring.datasource.driverClassName=org.postgresql.Driver
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.show-sql=false
app.api.swagger.enable=true
spring.main.banner-mode=off

如果有聪明人能解释为什么会发生这种情况,那就太酷了,因为天知道我在这个问题上纠结了多久。

【问题讨论】:

您的应用程序 jar 文件是否包含缺少的类? Unable to load class [...model.something.Something] 它的类没问题,但结果是整个 jar 有点损坏。我花了大约 4 个小时,然后决定在这里发布,但 5 分钟后才发现 jar 损坏。 【参考方案1】:

原来我的 JAR 依赖的注释处理器之一,即

annotationProcessor group: 'org.springframework.boot', name: 'spring-boot-configuration-processor', version: '2.5.3'

由于缺少实现语句而没有到达 JAR。

我通过添加修复它

implementation 'org.springframework.boot:spring-boot-configuration-processor:2.5.3';

作为我的bootJar gradle 任务的依赖项。

【讨论】:

以上是关于Docker中的SpringBoot + Postgres:在docker-compose上:无法初始化JPA EntityManagerFactory:无法加载类的主要内容,如果未能解决你的问题,请参考以下文章

Docker中的SpringBoot + Postgres:在docker-compose上:无法初始化JPA EntityManagerFactory:无法加载类

docker maven 出错:Failed to execute goal com.spotify:docker-maven-plugin:...: Request error: POST http

Docker中的Spring Boot未连接到Docker中的Mongo

SpringBoot与docker

SpringBoot与Docker1

关于SpringBoot过滤器过滤get及post请求中的XSS和SQL注入