Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
223 views
in Technique[技术] by (71.8m points)

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

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:

<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):

<?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:

@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-core dependency 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.

In Hibernate's POM, both jandex and classmate are defined as test dependencies, 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?

Thanks in advance for any pointers. - Vítor

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...