java 如果 Maven POM 将它们定义为测试范围,为什么 Hibernate 4.2 使用 jandex 和 classmate?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15168365/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 18:42:19  来源:igfitidea点击:

Why is Hibernate 4.2 using jandex and classmate if its Maven POM defines them as test scope?

javahibernateclassmate

提问by Vítor E. Silva Souza

I'm developing a simple example with Hibernate, using it outside any container. I'm using Maven, and thus configured the JBoss repository (see https://community.jboss.org/wiki/MavenGettingStarted-Users) and added the following dependencies to my project's POM:

我正在用 Hibernate 开发一个简单的例子,在任何容器之外使用它。我正在使用 Maven,因此配置了 JBoss 存储库(请参阅https://community.jboss.org/wiki/MavenGettingStarted-Users)并将以下依赖项添加到我的项目的 POM 中:

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>4.2.0.CR1</version>
</dependency>
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>1.3.170</version>
</dependency>

Then I proceeded to configure Hibernate to use H2 database like this (file hibernate.cfg.xml):

然后我继续配置 Hibernate 以使用这样的 H2 数据库(文件 hibernate.cfg.xml):

<?xml version='1.0' encoding='utf-8'?>
<hibernate-configuration xmlns="http://www.hibernate.org/xsd/hibernate-configuration">
    <session-factory>
        <property name="hibernate.connection.driver_class">org.h2.Driver</property>
        <property name="hibernate.connection.url">jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1;MVCC=TRUE</property>
        <property name="hibernate.connection.username">sa</property>
        <property name="hibernate.connection.password"></property>

        <property name="hibernate.connection.pool_size">1</property>
        <property name="hibernate.dialect">org.hibernate.dialect.H2Dialect</property>
        <property name="hibernate.cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.hbm2ddl.auto">update</property>
    </session-factory>
</hibernate-configuration>

Finally, I created a POJO for a simple contact class, as below:

最后,我为一个简单的联系人类创建了一个 POJO,如下所示:

@Entity
public class Contact {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Basic
    private String name;

    @Basic
    private String email;

    /* Getters and setters omitted for brevity. */
}

Finally, I created a class that obtains a session factory, a session and finally persists an entity. The code is as below:

最后,我创建了一个获取会话工厂、会话并最终持久化实体的类。代码如下:

    ServiceRegistry registry = new ServiceRegistryBuilder().configure().buildServiceRegistry();
    MetadataSources sources = new MetadataSources(registry);
    sources.addAnnotatedClass(Contact.class);
    Metadata metadata = sources.buildMetadata();
    sessionFactory = metadata.buildSessionFactory();

    Contact contact = new Contact();
    /* Set some attributes. */

    Session session = sessionFactory.openSession();
    session.save(contact);
    session.close();

When I run this code, this is what I get:

当我运行此代码时,这就是我得到的:

Exception in thread "main" java.lang.NoClassDefFoundError: org/jboss/jandex/Indexer
    at org.hibernate.metamodel.source.annotations.AnnotationMetadataSourceProcessorImpl.prepare(AnnotationMetadataSourceProcessorImpl.java:78)
    at org.hibernate.metamodel.source.internal.MetadataImpl.prepare(MetadataImpl.java:177)
    at org.hibernate.metamodel.source.internal.MetadataImpl.<init>(MetadataImpl.java:162)
    at org.hibernate.metamodel.source.internal.MetadataBuilderImpl.buildMetadata(MetadataBuilderImpl.java:83)
    at org.hibernate.metamodel.MetadataSources.buildMetadata(MetadataSources.java:112)

Investigating the POM of the org.hibernate/hibernate-coredependency that I added to my project, I can see it depends on org.jboss/jandex 1.0.3.Final. Satisfying that dependency, I get now a NoClassDefFoundError: com/fasterxml/classmate/TypeResolver. Back to Hibernate's POM, it depends on com.fasterxml/classmate 0.5.4. Satisfying that dependency also in my project I am finally able to execute the code without any NoClassDefFoundErrors.

调查org.hibernate/hibernate-core我添加到我的项目中的依赖项的 POM ,我可以看到它依赖于org.jboss/jandex 1.0.3.Final. 满足这种依赖性,我现在得到了一个NoClassDefFoundError: com/fasterxml/classmate/TypeResolver. 回到 Hibernate 的 POM,它取决于com.fasterxml/classmate 0.5.4. 在我的项目中也满足这种依赖关系,我终于能够在没有任何NoClassDefFoundErrors 的情况下执行代码。

In Hibernate's POM, both jandex and classmate are defined as testdependencies, and that's why they are not added automatically to my project by Maven's transitive dependency resolution feature. However, why are they being required when I run my simple code? What am I doing wrong?

在 Hibernate 的 POM 中,jandex 和 classmate 都被定义为test依赖项,这就是为什么 Maven 的传递依赖项解析功能不会将它们自动添加到我的项目中的原因。但是,为什么在我运行简单代码时需要它们?我究竟做错了什么?

Thanks in advance for any pointers. - Vítor

在此先感谢您的指点。- 维托

回答by Pace

Jandex and Classmate are not required for the main Hibernate functionality. They are required however for the metadata generation (reference). In order to not break things for people that don't use the metadata generation they added the dependencies as test dependencies. If you're using the metadata generation you will need to obtain those dependencies.

主要的 Hibernate 功能不需要 Jandex 和 Classmate。然而,它们是元数据生成所必需的(参考)。为了不破坏不使用元数据生成的人的事情,他们添加了依赖项作为测试依赖项。如果您使用元数据生成,则需要获取这些依赖项。