Problemas para obter Hibernate Core e Hibernate Annotations usando Apache Ivy (mas também é Maven2 relacionados.)
-
21-08-2019 - |
Pergunta
É uma longa um! ; -)
Há um monte de cópia colado texto nesta questão que faz com que pareça complicado. E para ser honesto, é um monte de informações! No entanto, para uma pessoa experiente muito do que pode ser desnecessário e fácil de deslizar sobre.
Na sua essência, eu só estou perguntando por que minha básica Hibernate Núcleo + Hibernate Annotations projeto de teste não funciona. Eu suspeito faltando dependências, mas eu estou usando Apache Ivy, que eu pensei que iria ficar transitivo dependências automaticamente a partir do ibiblio repositório Maven2, mas há claramente dependências que estão faltando (veja manchete menor no post sobre dependências).
Meu projeto de teste
Eu tenho um pequeno projeto de teste:
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;
}
}
O exceção que eu recebo quando eu executar o projeto de teste:
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
Se estiver faltando dependências
Como obter um ClassCastException (ele está incluído acima) eu pensei que seria uma boa idéia para verificar que eu tenho todas as dependências.
Se eu baixar o Hibernate Núcleo arquivo e olhar no diretório / lib de o arquivo eu recebo:
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
Se eu baixar os Hibernate Annotations e fazer a mesma coisa que eu recebo:
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
Por padrão Eu acho que Ivy usa os servidores ibiblio no modo Maven2 para recuperar suas dependências . Estou usando este ivy.xml para configurar quais dependências I quer:
<?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>
A dependência JAR está eu realmente começar são:
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
No POM-arquivo de hibernação-core em ibiblio há alguns linhas que Eu estou querendo saber sobre: ??
<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>
O que eles significam? Preciso de ambos? Por que eles são definidos como opcional se eles realmente estão sempre necessária? E como faço para obtê-los?
Solução 2
Eu tive que adicionar , opcional à minha ivy.xml também obter a configuração opcional, o que era necessário para todas as dependências para ser recuperados e para o projeto funcionar corretamente.
dependency org="org.hibernate" name="hibernate-core" rev="3.3.1.GA" conf="runtime->runtime,optional"/>
Outras dicas
Eu especificar explicitamente Javassist em seu projeto como uma dependência e seee se isso funciona.
Quanto ao porquê ele é listado como opcionais, existem várias razões que alguém faria isso, mas, neste caso, parece que a equipe Hibernate apenas não decidiu sobre o escopo dependência real:
<!-- optional deps for bytecode providers until those are finally properly scoped -->