簡體   English   中英

Maven 陰影 IllegalStateException - 缺少必需的 class 信息

[英]Maven shade IllegalStateException - Required class information is missing

我剛剛使用 JavaFX 和 Hibernate 構建了一個應用程序,它可以在 IntelliJ 上完美構建和運行,所以我選擇使用 Z402C5D9AF6B43711EA070BEE 生成一個“fat-jar”使用 jlink。

Jar 創建良好,它正確加載初始屏幕,但是當它嘗試連接到我的數據庫時,特別是這一行是有問題的(JPAUtil.java:19);

factory = Persistence.createEntityManagerFactory(persistenceUnit, properties);

我得到以下異常;

java.lang.IllegalStateException: Required class information is missing
    at org.jboss.jandex.Indexer.rebuildNestedType(Indexer.java:926)
    at org.jboss.jandex.Indexer.resolveTypePath(Indexer.java:786)
    at org.jboss.jandex.Indexer.resolveTypeAnnotation(Indexer.java:705)
    at org.jboss.jandex.Indexer.resolveTypeAnnotations(Indexer.java:613)
    at org.jboss.jandex.Indexer.index(Indexer.java:1602)
    at org.hibernate.boot.archive.scan.spi.ClassFileArchiveEntryHandler.toClassDescriptor(ClassFileArchiveEntryHandler.java:64)
    at org.hibernate.boot.archive.scan.spi.ClassFileArchiveEntryHandler.handleEntry(ClassFileArchiveEntryHandler.java:52)
    at org.hibernate.boot.archive.internal.JarFileBasedArchiveDescriptor.visitArchive(JarFileBasedArchiveDescriptor.java:147)
    at org.hibernate.boot.archive.scan.spi.AbstractScannerImpl.scan(AbstractScannerImpl.java:48)
    at org.hibernate.boot.model.process.internal.ScanningCoordinator.coordinateScan(ScanningCoordinator.java:76)
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.prepare(MetadataBuildingProcess.java:98)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.<init>(EntityManagerFactoryBuilderImpl.java:254)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.<init>(EntityManagerFactoryBuilderImpl.java:175)
    at org.hibernate.jpa.boot.spi.Bootstrap.getEntityManagerFactoryBuilder(Bootstrap.java:76)
    at org.hibernate.jpa.HibernatePersistenceProvider.getEntityManagerFactoryBuilder(HibernatePersistenceProvider.java:171)
    at org.hibernate.jpa.HibernatePersistenceProvider.getEntityManagerFactoryBuilderOrNull(HibernatePersistenceProvider.java:119)
    at org.hibernate.jpa.HibernatePersistenceProvider.getEntityManagerFactoryBuilderOrNull(HibernatePersistenceProvider.java:61)
    at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:50)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:79)
    at com.it.util.JPAUtil.getEntityManagerFactory(JPAUtil.java:19)
    at com.it.controller.HomeController.initializeSettings(HomeController.java:1571)
    at com.it.controller.HomeController.initialize(HomeController.java:1407)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2573)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2466)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3237)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3194)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3163)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3136)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3113)
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3106)
    at com.it.Home.start(Home.java:23)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
    at java.base/java.lang.Thread.run(Thread.java:834)

我知道語法是正確的,正如我之前提到的它在 IDE 上正確運行,所以我懷疑它在由陰影生成的 jar 文件中丟失了一些東西,但是我已經花了將近 3 天的時間在這上面,我根本找不到原因。 stacktrace 上顯示的信息沒有多大幫助,至少我什么也沒看到——我什至查看了 stacktrace 中提到的所有類,它們似乎都在生成的 Jar 上。 希望這里的任何人在 maven 陰影過程中都有類似的或可能比我更熟悉的東西。 任何幫助或看點將不勝感激。

有助於識別問題的其他文件如下;

persistence.xml - 其他屬性從代碼上的 XML 文件加載。

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.2" xmlns="http://xmlns.jcp.org/xml/ns/persistence" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd">
    
    <persistence-unit name="Project-Postgre">
        <description>Hibernate JPA Configuration</description>
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    
        <properties>
            <property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver" />
            <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
            
            <property name="hibernate.show_sql" value="false" />
            <property name="hibernate.format_sql" value = "false" />
        </properties>
    </persistence-unit>
</persistence>

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.it</groupId>
    <artifactId>Project</artifactId>
    <version>1.0</version>
    <packaging>jar</packaging>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <maven.compiler.release>11</maven.compiler.release>
        <javafx.version>14</javafx.version>
    </properties>

    <name>Project</name>

    <dependencies>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>${javafx.version}</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>${javafx.version}</version>
        </dependency>
        <dependency>
            <groupId>javax.persistence</groupId>
            <artifactId>javax.persistence-api</artifactId>
            <version>2.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>4.1.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.1.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/de.jensd/fontawesomefx -->
        <dependency>
            <groupId>de.jensd</groupId>
            <artifactId>fontawesomefx</artifactId>
            <version>8.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.4.20.Final</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.postgresql/postgresql -->
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>42.2.15</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.oracle.database.jdbc/ojdbc10 -->
        <dependency>
            <groupId>com.oracle.database.jdbc</groupId>
            <artifactId>ojdbc10</artifactId>
            <version>19.7.0.0</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <release>${maven.compiler.release}</release>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.openjfx</groupId>
                <artifactId>javafx-maven-plugin</artifactId>
                <version>0.0.3</version>
                <configuration>
                    <mainClass>com.it.HomeFX</mainClass>
                </configuration>
            </plugin>


            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.2.0</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <shadedArtifactAttached>true</shadedArtifactAttached>
                            <shadedClassifierName>project-classifier</shadedClassifierName>
                            <outputFile>target\shade\${project.artifactId}.jar</outputFile>
                            <transformers>
                                <transformer implementation=
                                                     "org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>com.it.HomeFX</mainClass>
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

JPAUtil

public static EntityManagerFactory getEntityManagerFactory(String persistenceUnit, String connectionURL, String user, String password) {
        if (factory == null) {
            Map<String, String> properties = new HashMap<>();
            properties.put("javax.persistence.jdbc.url", connectionURL);
            properties.put("javax.persistence.jdbc.user", user);
            properties.put("javax.persistence.jdbc.password", password);
            factory = Persistence.createEntityManagerFactory(persistenceUnit, properties);
        }
        return factory;
}

我有同樣的錯誤使用: spring.version:5.2.7.RELEASE spring.boot.version:2.3.1.RELEASE postgresql-version:42.2.16

從 42.2.15 開始的所有版本的 postgres 都會發生這種情況。 版本 42.2.14(或更早版本)對我來說很好用。

我有同樣的問題。 我嘗試將 PostgreSQL JDBC 驅動程序版本降級為 42.0.0。 異常消失了,一切正常。

該問題是由javac 1.8 生成的無效字節碼引起的(例如,已知 AdoptOpenJDK 1.8u222 會受到影響)。

這是問題(使用復制器): https://github.com/wildfly/jandex/issues/92

修復方法是更新到org.jboss:jandex:2.2.3.Final ,其中包括解決方法(以及其他一些針對類型注釋的修復),或者使用 Java 11 編譯器(== javac 11)。


以防萬一, org.postgresql:postgresql:42.2.15會觸發該問題,因為它使用Checker Framework進行空值驗證,並且它包含多個@Nullable@NonNull注釋以使驗證通過。

即將推出的org.postgresql:42.2.18org.postgresql:42.3.0將具有相關的解決方法,因此它也適用於舊的jandex版本。


If you are reading here, I would recommend adding forbidden-apis and jandex bytecode parsers (eg de.thetaphi.forbiddenapis and com.github.vlsi.jandex Gradle plugins) to your build pipeline to capture invalid bytecode early (which might otherwise come unnoticed ),特別是如果您仍然使用javac 1.8。

通過從 Hibernate 切換到 OpenJPA,我設法克服了這個問題。 Hibernate 沒有提供足夠的信息來調試問題,當切換到 OpenJPA 時,我只需將其添加到我的 pom.xml;

<dependency>
     <groupId>org.apache.openjpa</groupId>
     <artifactId>openjpa-all</artifactId>
     <version>3.1.2</version>
</dependency>

Shade 使用所有必需的庫創建了 JAR,並且成功連接到數據庫。

Eventually, fixed in PostgreSQL JDBC Driver version 42.2.19, see https://jdbc.postgresql.org/documentation/changelog.html#version_42.2.19 .

將您的版本更新到 42.2.19,它應該可以解決問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM