Java - Hibernate 无法在 Jar 中运行

问题描述

我们使用 Hibernate Envers 来保存对象更改历史记录。它在开发中运行良好,现在我们已经用代码构建了一个 JAR,它不再工作了。我们尝试了很多事情,例如升级检查数据库连接是否正确等。在 Intellij 本身中运行时一切正常,但在运行编译后的 JAR 时却没有。

我们在初始化 Hibernate 会话工厂时遇到了这个问题,在收到此错误时我们没有进行任何事务。很多在线答案都针对无法正确访问会话的上下文提供了解决方案,但此处并非如此。

build.gradle

plugins {
    id 'org.jetbrains.kotlin.jvm' version '1.3.41'
}
apply plugin: 'java'
apply plugin: 'maven-publish'
apply plugin: 'idea'
apply plugin: 'kotlin'

group = 'com.obscured'
version = '1.0'
description = "Obscured API"

compileJava {
    sourceCompatibility = 1.8
    targetCompatibility = 1.8
}

tasks.withType(JavaCompile) {
    options.encoding = 'UTF-8'
}

repositories {
    maven { url 'https://maven.google.com' }
    mavenCentral()
    jcenter()
}

dependencies {
    testImplementation group: 'junit',name: 'junit',version: '4.12'
    implementation group: 'commons-codec',name: 'commons-codec',version: '1.10'
    implementation group: 'com.sparkjava',name: 'spark-core',version: '2.9.3'
    implementation group: 'org.slf4j',name: 'slf4j-api',version: '1.7.5'
    implementation group: 'org.slf4j',name: 'slf4j-log4j12',version: '1.7.5'
    implementation group: 'org.json',name: 'json',version: '20170516'
    implementation group: 'de.mkammerer',name: 'argon2-jvm',version: '2.2'
    implementation group: 'com.maxmind.geoip2',name: 'geoip2',version: '2.9.0'
    implementation group: 'javax.mail',name: 'mail',version: '1.4'
    implementation group: 'com.stripe',name: 'stripe-java',version: '16.1.0'
    implementation group: 'com.googlecode.owasp-java-html-sanitizer',name: 'owasp-java-html-sanitizer',version: '20191001.1'
    implementation group: 'com.google.code.geocoder-java',name: 'geocoder-java',version: '0.16'
    implementation group: 'MysqL',name: 'mysql-connector-java',version: '8.0.18'
    implementation group: 'org.flywaydb',name: 'flyway-core',version: '5.1.4'

    implementation group: 'org.hibernate',name: 'hibernate-core',version: '5.4.30.Final'
    implementation group: 'org.hibernate',name: 'hibernate-entitymanager',name: 'hibernate-c3p0',name: 'hibernate-ehcache',name: 'hibernate-envers',version: '5.4.30.Final'
    implementation group: 'org.hibernate.search',name: 'hibernate-search-mapper-orm',version: '6.0.1.Final'
    implementation group: 'org.hibernate.search',name: 'hibernate-search-backend-lucene',version: '6.0.1.Final'

    implementation group: 'com.google.firebase',name: 'firebase-admin',version: '7.0.0'

    implementation group: 'com.github.hotchemi',name: 'khronos',version: '0.9.0'
    implementation group: 'org.everit.json',name: 'org.everit.json.schema',version: '1.5.1'
    implementation group: 'org.jsoup',name: 'jsoup',version: '1.11.3'
    implementation group: 'com.amazonaws',name: 'aws-java-sdk',version: '1.11.688'
    implementation 'com.google.maps:google-maps-services:0.11.0'
    implementation 'com.google.firebase:firebase-admin:6.12.2'
    implementation 'com.auth0:java-jwt:3.10.3'

    implementation group: 'org.reflections',name: 'reflections',version: '0.9.12'
    implementation group: 'javax.ws.rs',name: 'javax.ws.rs-api',version: '2.1.1'

    // Swagger
    implementation group: 'io.swagger.core.v3',name: 'swagger-core',version: '2.1.6'
    implementation group: 'io.swagger.core.v3',name: 'swagger-jaxrs2',name: 'swagger-jaxrs2-servlet-initializer',name: 'swagger-annotations',version: '2.1.4'

    implementation 'io.github.cdimascio:java-dotenv:3.0.0'
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
}

task fatJar(type: Jar) {
    zip64 = true
    archiveName = 'obscured.jar'
    manifest {
        attributes 'Main-Class': 'com.obscured.Obscured'
    }
    exclude 'meta-inf/*.RSA','meta-inf/*.SF','meta-inf/*.DSA'
    from {
        configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
        configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) }
    }
    with jar
}

sourceSets {
    main.java.srcDirs += 'src/main/kotlin/'
    test.java.srcDirs += 'src/test/kotlin/'
}

compileKotlin {
    kotlinoptions {
        jvmTarget = "1.8"
    }
}

compileTestKotlin {
    kotlinoptions {
        jvmTarget = "1.8"
    }
}

我们运行的命令(在主目录中,只是为了安全):

java -jar obscured.jar

发生错误的地方正在执行的代码

try {
    val cfg = Configuration()
    cfg.configure("db/hibernate.cfg.xml")
    cfg.setProperty("hibernate.connection.url","jdbc:MysqL://" + this.host + ":" + this.port?.toString() + "/" + this.database + "?autoReconnect=true")
    cfg.setProperty("hibernate.connection.username",this.username)
    cfg.setProperty("hibernate.connection.password",this.password)
    factory = cfg.buildSessionFactory()
} catch (ex: Throwable) {
    System.err.println("Failed user create sessionFactory object.$ex")
    throw ExceptionInInitializerError(ex)
}

我们得到的错误

Caused by: org.hibernate.service.UnkNownServiceException: UnkNown service requested [org.hibernate.envers.boot.internal.EnveRSService]
        at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:210)
        at org.hibernate.envers.boot.internal.TypeContributorImpl.contribute(TypeContributorImpl.java:22)
        at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.handleTypes(MetadataBuildingProcess.java:391)
        at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:132)
        at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.build(MetadataBuildingProcess.java:86)
        at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:473)
        at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:84)
        at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:689)
        at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:724)
        at com.obscured.database.Connection.configureHibernate(Connection.kt:69)
        ... 2 more

再说一次,一旦它在 JAR 中,这似乎就会发生,所有依赖项都可用并且运行良好。我们已经尝试使用多个不同版本的 Hibernate 依赖项,但这似乎对我们来说是一个全面的问题。

我们甚至对 JAR 进行了反编译,以查看是否存在与 IDE 中相同的文件,并且确实存在,因此没有运气。我们显然已经在互联网上搜索了答案,但没有肯定的结果。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)