Trouble getting Hibernate Core and Hibernate Annotations using Apache Ivy (but it's also Maven2 related.)

user14070 picture user14070 · Feb 6, 2009 · Viewed 26.4k times · Source

It's a long one! ;-)

There are a lot of copy pasted text in this question which makes it look complicated. And to be honest, it's a lot of information! However to an experienced person a lot of it might be unnecessary and easy to skim over.

In its essence I'm only wondering why my basic Hibernate Core + Hibernate Annotations test project doesn't work. I suspect missing dependencies, but I'm using Apache Ivy which I thought would get transitive dependencies automatically from the Maven2 repository ibiblio, but there clearly are dependencies missing (see headline lower in the post about dependencies).

My test project

I have a small test project:

hibernate.cfg.xml

 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE hibernate-configuration PUBLIC
         "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
         "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
 <hibernate-configuration>
     <session-factory>
         <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
         <property name="connection.url">jdbc:mysql://localhost:3306/webcookieschema</property>
         <property name="connection.username">webcookieuser</property>
         <property name="connection.password">tHePaSsWoRd</property>
         <property name="dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
         </session-factory>
 </hibernate-configuration>

Test.java

 public class Test {
    public static void main(String[] args) {
        UserDAO udao = new HibernateUserDAO();
        User u = new User();
        u.setName("somename");
        udao.store(u);
    }
 }

HibernateUserDAO.java

 import org.hibernate.Session;
 import org.hibernate.SessionFactory;
 import org.hibernate.Transaction;
 import org.hibernate.cfg.AnnotationConfiguration;

 public class HibernateUserDAO implements
        UserDAO {

    private SessionFactory sessionFactory;

    public HibernateUserDAO() {
        AnnotationConfiguration annotConf = new AnnotationConfiguration();
        annotConf.addAnnotatedClass(User.class);
        annotConf.configure();
        // The line below generates the exception!
        sessionFactory = annotConf.buildSessionFactory();
    }

    @Override
    public void store(User user) {
        Session session = sessionFactory.openSession();
        Transaction tx = session.getTransaction();
        try {
            tx.begin();
            session.saveOrUpdate(user);
            tx.commit();
        } catch (RuntimeException e) {
            tx.rollback();
            throw e;
        } finally {
            session.close();
        }
    }
 }

log4j.properties

 log4j.appender.Stdout=org.apache.log4j.ConsoleAppender
 log4j.appender.Stdout.layout=org.apache.log4j.PatternLayout
 log4j.appender.Stdout.layout.conversionPattern=%-5p - %-26.26c{1} - %m\n

 log4j.rootLogger=INFO,Stdout

 log4j.logger.org.apache.wicket=INFO
 log4j.logger.org.apache.wicket.protocol.http.HttpSessionStore=INFO
 log4j.logger.org.apache.wicket.version=INFO
 log4j.logger.org.apache.wicket.RequestCycle=INFO

UserDAO.java

 public interface UserDAO {
    public void store(User user);
 }

User.java

 import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.GeneratedValue;
 import javax.persistence.Id;

 @Entity
 public class User {
    @Id
    @GeneratedValue
    @Column(name = "ID")
    private Long id;

    @Column(name = "NAME")
    private String name;

    public User() {
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
 }

The exception I get when I run the test project:

Exception in thread "main" java.lang.NoClassDefFoundError: javassist/util/proxy/MethodFilter
at org.hibernate.bytecode.javassist.BytecodeProviderImpl.getProxyFactoryFactory(BytecodeProviderImpl.java:49)
at org.hibernate.tuple.entity.PojoEntityTuplizer.buildProxyFactoryInternal(PojoEntityTuplizer.java:203)
at org.hibernate.tuple.entity.PojoEntityTuplizer.buildProxyFactory(PojoEntityTuplizer.java:181)
at org.hibernate.tuple.entity.AbstractEntityTuplizer.<init>(AbstractEntityTuplizer.java:158)
at org.hibernate.tuple.entity.PojoEntityTuplizer.<init>(PojoEntityTuplizer.java:76)
at org.hibernate.tuple.entity.EntityEntityModeToTuplizerMapping.<init>(EntityEntityModeToTuplizerMapping.java:80)
at org.hibernate.tuple.entity.EntityMetamodel.<init>(EntityMetamodel.java:325)
at org.hibernate.persister.entity.AbstractEntityPersister.<init>(AbstractEntityPersister.java:457)
at org.hibernate.persister.entity.SingleTableEntityPersister.<init>(SingleTableEntityPersister.java:131)
at org.hibernate.persister.PersisterFactory.createClassPersister(PersisterFactory.java:84)
at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:261)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1327)
at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:867)
at HibernateUserDAO.<init>(HibernateUserDAO.java:15)
at Test.main(Test.java:3)
Caused by: java.lang.ClassNotFoundException:
    javassist.util.proxy.MethodFilter
    at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:276)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
    at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
    ... 15 more

If it's missing dependencies

As I get a ClassCastException (it's included above) I thought it would be a good idea to check that I have all dependencies.

If I download the Hibernate Core archive and look in the /lib directory of the archive I get:

kent@rat:~/dl-web/hibernate-distribution-3.3.1.GA$ tree lib/
lib/
|-- bytecode
|   |-- cglib
|   |   `-- hibernate-cglib-repack-2.1_3.jar
|   `-- javassist
|       `-- javassist-3.4.GA.jar
|-- optional
|   |-- c3p0
|   |   `-- c3p0-0.9.1.jar
|   |-- ehcache
|   |   `-- ehcache-1.2.3.jar
|   |-- jbosscache
|   |   `-- jboss-cache-1.4.1.GA.jar
|   |-- jbosscache2
|   |   `-- jbosscache-core-2.1.1.GA.jar
|   |-- oscache
|   |   `-- oscache-2.1.jar
|   |-- proxool
|   |   `-- proxool-0.8.3.jar
|   `-- swarmcache
|       `-- swarmcache-1.0RC2.jar
`-- required
    |-- antlr-2.7.6.jar
    |-- commons-collections-3.1.jar
    |-- dom4j-1.6.1.jar
    |-- javassist-3.4.GA.jar
    |-- jta-1.1.jar
    `-- slf4j-api-1.5.2.jar

If I download the Hibernate Annotations and do the same thing I get:

kent@rat:~/dl-web/hibernate-annotations-3.4.0.GA$ tree lib/
lib/
|-- README.txt
|-- build
|   |-- ant-contrib-1.0b2.jar
|   |-- ant-junit-1.6.5.jar
|   `-- junit-3.8.1.jar
|-- dom4j.jar
|-- ejb3-persistence.jar
|-- hibernate-commons-annotations.jar
|-- hibernate-core.jar
|-- slf4j-api.jar
`-- test
    |-- antlr.jar
    |-- asm-attrs.jar
    |-- asm.jar
    |-- commons-collections.jar
    |-- javassist.jar
    |-- jta.jar
    |-- junit.jar
    |-- log4j.jar
    `-- slf4j-log4j12.jar

By default I think Ivy uses the ibiblio servers in Maven2 mode to retrieve its dependencies. I'm using this ivy.xml to configure which dependencies I want:

<?xml version="1.0" encoding="UTF-8"?>
<ivy-module version="2.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd">
    <info
      organisation="testorganization"
      module="hibernatetest"
      status="integration"/>
    <configurations>
        <conf name="runtime" description="" />
    </configurations>
    <dependencies>
        <dependency org="mysql" name="mysql-connector-java" rev="5.1.6" conf="runtime->default"/>
        <dependency org="org.hibernate" name="hibernate-core" rev="3.3.1.GA" conf="runtime->default"/>
        <dependency org="org.hibernate" name="hibernate-annotations" rev="3.4.0.GA" conf="runtime->default">
            <include></include>
        </dependency>
        <dependency org="org.slf4j" name="slf4j-log4j12" rev="1.5.6" conf="runtime->default"/>
    </dependencies>
</ivy-module>

The dependency JAR's I actually get are:

kent@rat:~/.ivy2/cache$ ls -R1 * | egrep '.jar$'
antlr-2.7.6.jar
commons-collections-3.1.jar
dom4j-1.6.1.jar
jta-1.1.jar
log4j-1.2.14.jar
mysql-connector-java-5.1.6.jar
ejb3-persistence-1.0.2.GA.jar
hibernate-annotations-3.4.0.GA.jar
hibernate-commons-annotations-3.1.0.GA.jar
hibernate-core-3.3.1.GA.jar
slf4j-api-1.5.6.jar
slf4j-log4j12-1.5.6.jar
xml-apis-1.0.b2.jar

In the POM-file for hibernate-core on ibiblio there are some lines which I'm wondering about:

   <dependencies>
       ...
       ...
       ...
       <!-- optional deps for bytecode providers until those are finally properly scoped -->
       <dependency>
           <groupId>javassist</groupId>
           <artifactId>javassist</artifactId>
           <version>3.4.GA</version>
           <optional>true</optional>
       </dependency>
       <dependency>
           <groupId>org.hibernate</groupId>
           <artifactId>hibernate-cglib-repack</artifactId>
           <version>2.1_3</version>
           <optional>true</optional>
       </dependency>
   </dependencies>

What do they mean? Do I need both of them? Why are they set as optional if they are really always required? And how do I get them?

Answer

Jack Leow picture Jack Leow · Feb 7, 2009

I'd explicitly specify javassist in your project as a dependency and seee if that works.

As to why it's listed as optional, there are several reasons someone would do that, but in this case, it looks like the Hibernate team just hasn't decided on the actual dependency scope:

<!-- optional deps for bytecode providers until those are finally properly scoped -->