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

14,428

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.

Share:
14,428

Related videos on Youtube

Vítor E. Silva Souza
Author by

Vítor E. Silva Souza

Computer Science professor at Ufes, Brazil. Check my website for more information: http://www.inf.ufes.br/~vitorsouza

Updated on September 16, 2022

Comments

  • Vítor E. Silva Souza
    Vítor E. Silva Souza over 1 year

    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

  • Vítor E. Silva Souza
    Vítor E. Silva Souza about 11 years
    Thank you. I'll keep the dependencies in my pom.xml, then.