我有一个由我构建的小项目,它是用Java编写的,使用Hibernate 5,Hibernate Search 5.5,Log4j2并访问PostgreSQL的3个数据库(其中2个验证了他们的元数据,另外一个创建了含量)。
问题在于,这是一种非常奇怪的行为,我试图向大家解释。
当我在Eclipse中启动Main类时,程序运行良好,如预期的那样。当我生成JAR并使用命令shell执行它时,问题就来了......这就是堆栈trace。
Exception in thread "main" java.lang.ExceptionInInitializerError
Caused by: org.hibernate.service.UnknownServiceException: Unknown service requested [org.hibernate.search.hcore.impl.SearchFactoryReference]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:184)
at org.hibernate.search.hcore.impl.HibernateSearchSessionFactoryObserver.sessionFactoryCreated(HibernateSearchSessionFactoryObserver.java:86)
at org.hibernate.internal.SessionFactoryObserverChain.sessionFactoryCreated(SessionFactoryObserverChain.java:35)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:541)
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:444)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:708)
at dao.paradasws.ServiceDaoParadasWs.getSessionFactory(ServiceDaoParadasWs.java:89)
at dao.AbstractDao.<init>(AbstractDao.java:27)
at dao.paradasws.ServiceDaoParadasWs.<init>(ServiceDaoParadasWs.java:36)
at tasks.Main.<clinit>(Main.java:49)
我获得例外的方法如下:
@Override
protected SessionFactory getSessionFactory() throws HibernateException {
if(getFactory() == null){
// Configuramos hibernate:
Configuration cfg = new Configuration();
// Dialecto PostgreSQL:
//cfg.setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQL9Dialect");
// Dialecto Postgis:
cfg.setProperty("hibernate.dialect", "org.hibernate.spatial.dialect.postgis.PostgisDialect");
cfg.setProperty("hibernate.connection.driver_class", "org.postgresql.Driver");
// Linux Server
cfg.setProperty("hibernate.connection.url", "jdbc:postgresql://localhost:5432/database");
cfg.setProperty("hibernate.connection.username", "postgres");
cfg.setProperty("hibernate.connection.password", "postgres");
cfg.setProperty("hibernate.hbm2ddl.auto", "validate");
cfg.setProperty("show_sql", "true");
cfg.setProperty("hibernate.connection.pool_size", "5000");
// C3p0 connection pool
// cfg.setProperty("connection.provider_class", "org.hibernate.connection.C3P0ConnectionProvider");
// cfg.setProperty("c3p0.min_size", "7");
// cfg.setProperty("c3p0.max_size", "1000");
// cfg.setProperty("c3p0.timeout", "1000");
// cfg.setProperty("c3p0.idle_test_period", "2000");
// cfg.setProperty("c3p0.preferredTestQuery", "select 1;");
// cfg.setProperty("hibernate.connection.release_mode", "after_transaction");
// Hibernate search:
cfg.setProperty("hibernate.search.default.directory_provider", "filesystem");
cfg.setProperty("hibernate.search.default.indexBase", "indexLucene");
cfg.setProperty("hibernate.current_session_context_class", "thread");
cfg.addAnnotatedClass(OperadorWS.class);
cfg.addAnnotatedClass(ParadaWS.class);
StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder();
builder.applySettings(cfg.getProperties());
StandardServiceRegistry serviceRegistry = builder.build();
setFactory(cfg.buildSessionFactory(serviceRegistry));
setStats(getFactory().getStatistics());
getStats().setStatisticsEnabled(true);
}
return super.getFactory();
}
以防万一需要,我发布了我的pom.xml文件:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany</groupId>
<artifactId>autom</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<!-- NOTE: We don't need a groupId specification because the group is
org.apache.maven.plugins ...which is assumed by default.
-->
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<classpathMavenRepositoryLayout>true</classpathMavenRepositoryLayout>
<mainClass>tasks.Main</mainClass>
<addExtensions>true</addExtensions>
<classpathLayoutType>repository</classpathLayoutType>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<classpathMavenRepositoryLayout>true</classpathMavenRepositoryLayout>
<mainClass>tasks.Main</mainClass>
<addExtensions>true</addExtensions>
<classpathLayoutType>repository</classpathLayoutType>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<!-- or whatever version you use -->
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<commons-lang.version>3.4</commons-lang.version>
<commons-csv.version>1.2</commons-csv.version>
<log4j.version>2.4.1</log4j.version>
<postgresql-jdbc.version>9.1-901.jdbc4</postgresql-jdbc.version>
<hibernate.version>5.0.5.Final</hibernate.version>
<hibernate-validator.version>5.2.2.Final</hibernate-validator.version>
<javax-el-api.version>2.2.4</javax-el-api.version>
<hibernate-search.version>5.5.1.Final</hibernate-search.version>
<simmetrics.version>4.0.1</simmetrics.version>
</properties>
<dependencies>
<!-- Commons CSV -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-csv</artifactId>
<version>${commons-csv.version}</version>
</dependency>
<!-- Apache Commons Lang -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang.version}</version>
</dependency>
<!-- Log4j -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j.version}</version>
</dependency>
<!-- <dependency> -->
<!-- <groupId>org.apache.logging.log4j</groupId> -->
<!-- <artifactId>log4j-slf4j-impl</artifactId> -->
<!-- <version>${log4j.version}</version> -->
<!-- </dependency> -->
<!--HIBERNATE LOGGER (log4j)-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.6</version>
<exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Old JDBC4 for PostgreSQL 9.1 -->
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>${postgresql-jdbc.version}</version>
</dependency>
<!-- Hibernate -->
<dependency><!-- Core -->
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency><!-- c3p0 -->
<groupId>org.hibernate</groupId>
<artifactId>hibernate-c3p0</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency><!-- postgis/spatial -->
<groupId>org.hibernate</groupId>
<artifactId>hibernate-spatial</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency><!-- hibernate validator -->
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>${hibernate-validator.version}</version>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>${javax-el-api.version}</version>
</dependency>
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
<version>1.1</version>
</dependency>
<dependency><!-- hibernate search -->
<groupId>org.hibernate</groupId>
<artifactId>hibernate-search-orm</artifactId>
<version>${hibernate-search.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-search-engine</artifactId>
<version>${hibernate-search.version}</version>
</dependency>
<dependency>
<groupId>com.github.mpkorstanje</groupId>
<artifactId>simmetrics-core</artifactId>
<version>${simmetrics.version}</version>
</dependency>
</dependencies>
</project>
有人知道为什么我会收到这个奇怪的错误吗?
修改:
根据要求,我将发布整个班级和超类。
AbstractDao的:
package dao;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.search.FullTextSession;
import org.hibernate.search.Search;
import org.hibernate.search.SearchFactory;
import org.hibernate.stat.Statistics;
public abstract class AbstractDao {
private Session currentSession;
private Transaction currentTransaction;
private SessionFactory factory;
private Statistics stats;
/**
* Hibernate Search Engine
*/
private FullTextSession fullTextSession = null;
private SearchFactory searchFactory = null;
protected AbstractDao(){
factory = getSessionFactory();
}
public Session openCurrentSession() throws HibernateException {
if(currentSession == null || !currentSession.isOpen())
currentSession = factory.openSession();
return currentSession;
}
public Session openCurrentSessionwithTransaction() throws HibernateException {
if(currentSession == null || !currentSession.isOpen())
currentSession = factory.openSession();
currentTransaction = currentSession.beginTransaction();
return currentSession;
}
public void closeCurrentSession() {
currentSession.close();
}
public void closeCurrentSessionwithTransaction() {
currentTransaction.commit();
currentSession.close();
}
protected abstract SessionFactory getSessionFactory() throws HibernateException;
public Session getCurrentSession() {
return currentSession;
}
public void setCurrentSession(Session currentSession) {
this.currentSession = currentSession;
}
public Transaction getCurrentTransaction() {
return currentTransaction;
}
public void setCurrentTransaction(Transaction currentTransaction) {
this.currentTransaction = currentTransaction;
}
public void commitTransaction(){
if(currentTransaction != null)
currentTransaction.commit();
}
public void rollbackTransaction(){
if(currentTransaction != null)
currentTransaction.rollback();
}
/**
@return the factory
*/
public SessionFactory getFactory() {
return factory;
}
/**
@param factory the factory to set
*/
public void setFactory(SessionFactory factory) {
this.factory = factory;
}
/**
@return the stats
*/
public Statistics getStats() {
return stats;
}
/**
@param stats the stats to set
*/
public void setStats(Statistics stats) {
this.stats = stats;
}
/**
@return the fullTextSession
*/
public FullTextSession getFullTextSession() {
return fullTextSession;
}
/**
@param fullTextSession the fullTextSession to set
*/
public void setFullTextSession(FullTextSession fullTextSession) {
this.fullTextSession = fullTextSession;
}
protected SearchFactory getHibernateSearch(){
if(fullTextSession == null){
fullTextSession = Search.getFullTextSession(getCurrentSession());
}
if(searchFactory == null){
searchFactory = fullTextSession.getSearchFactory();
}
return searchFactory;
}
/**
@return the searchFactory
*/
public SearchFactory getSearchFactory() {
return searchFactory;
}
/**
@param searchFactory the searchFactory to set
*/
public void setSearchFactory(SearchFactory searchFactory) {
this.searchFactory = searchFactory;
}
public void finish() throws Throwable{
Session session = getCurrentSession();
if(session != null)
session.close();
if(factory != null)
factory.close();
}
}
ServiceDAOParadasWS类:
package dao.paradasws;
import java.util.List;
import org.apache.lucene.search.Query;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.criterion.Restrictions;
import org.hibernate.search.FullTextQuery;
import org.hibernate.search.FullTextSession;
import org.hibernate.search.SearchFactory;
import org.hibernate.search.query.dsl.QueryBuilder;
import dao.AbstractDao;
import model.paradasws.OperadorWS;
import model.paradasws.ParadaWS;
public class ServiceDaoParadasWs extends AbstractDao implements IDaoParadasWs {
public ServiceDaoParadasWs(){
super();
}
@Override
protected SessionFactory getSessionFactory() throws HibernateException {
// already posted
}
@Override
public List<ParadaWS> getParadas() {
openCurrentSession();
@SuppressWarnings("unchecked")
List<ParadaWS> paradasWs = (List<ParadaWS>) getCurrentSession().createQuery("from ParadaWS").list();
return paradasWs;
}
@Override
public List<ParadaWS> getParadaPorNombre(String pDescripcionCorta, OperadorWS pOperador) {
openCurrentSession();
Criteria c = getCurrentSession().createCriteria(ParadaWS.class);
c.add(
Restrictions.and(
Restrictions.eq("descripcionCorta", pDescripcionCorta).ignoreCase(),
Restrictions.eq("operador", pOperador)
)
);
@SuppressWarnings("unchecked")
List<ParadaWS> paradas = c.list();
return paradas;
}
@Override
public OperadorWS getOperador(Integer pId) {
openCurrentSession();
Criteria c = getCurrentSession().createCriteria(OperadorWS.class);//createQuery("from OperadorWS op where op.codigoOperador=:id");
c.add(Restrictions.eq("codigoOperador", pId));
OperadorWS op = (OperadorWS) c.uniqueResult();
return op;
}
public void indexarParadas(){
openCurrentSession();
getHibernateSearch();
FullTextSession txtSession = getFullTextSession();
txtSession.getTransaction().begin();
@SuppressWarnings("unchecked")
List<ParadaWS> paradas = txtSession.createQuery("from ParadaWS").list();
for (ParadaWS paradaWS : paradas) {
txtSession.index(paradaWS);
}
txtSession.getTransaction().commit();
}
@SuppressWarnings("unchecked")
public List<ParadaWS> buscarSimilitudesNombreParada(String pNombreCorto){
openCurrentSession();
SearchFactory fact = getHibernateSearch();
FullTextSession txtSession = getFullTextSession();
QueryBuilder b = fact.buildQueryBuilder().forEntity(ParadaWS.class).get();
Query query = b.keyword()
.fuzzy()
.withEditDistanceUpTo(2)
.onField("descripcionCorta")
.matching(pNombreCorto)
.createQuery();
FullTextQuery txtQuery = txtSession.createFullTextQuery(query, ParadaWS.class);
return (List<ParadaWS>) txtQuery.list();
}
}
请注意,AbstractDAO的实现者必须覆盖getSessionFactory()方法(此处引发异常)。
答案 0 :(得分:1)
该错误表示在启动Hibernate ORM SessionFactory 时未在类路径中找到Hibernate Search 服务。
这些类似乎就在那里(因为你在堆栈跟踪中成功加载了 org.hibernate.search.hcore.impl.HibernateSearchSessionFactoryObserver )。
所以我猜测 maven-assembly-plugin 插件未能包含来自Hibernate Search jar的服务定义。
具体来说,您似乎错过了 META-INF / services / 中的这些定义:
我对Maven插件不够熟悉,无法建议你应该如何配置它,但我认为它可以使用不同的配置。
我建议尝试让它工作,而不是试图重新包装它:使用普通的类路径和我们发布的原始罐子应该正常工作。
答案 1 :(得分:0)
我已经能够导出可行的可执行JAR ......
在Eclipse中,右键单击您的项目;出口;选择Runnable JAR文件;选择启动配置,导出目标(类似于myfile.jar),选择将所需的包打包到生成的JAR中,然后按Finish。
我不知道为什么,但这种方式并没有给我任何错误,我可以执行它。嗯,说实话,有一点是它没有工作:log4j2,这就是,日志还没有创建。如果我将log4j2.xml文件从/ resources移动到/,则会创建日志。