从外部jar或外部类路径动态加载的Map实体

时间:2014-12-04 21:36:55

标签: java hibernate groovy classloader

我需要映射未在hibernate.cfg.xml中列出的实体,这些类是动态加载的 来自一个任意文件夹。我试图注册一个ClassLoaderService来改变加载行为, 如果类在编译时定义并存在于类路径中,则以下代码运行正常,但是如果 我尝试映射一个dinamically加载的类我得到ClassNotFoundException。关于同一个问题有一些问题,但我找不到任何可行的解决方案。

URL file = ConsultaBase.class.getProtectionDomain().getCodeSource().getLocation().toURI().resolve("implementacao/").resolve("hibernate.cfg.xml").toURL(); 
Configuration configuration = new Configuration()
    .addAnnotatedClass(Registro.class).configure(file);         

ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder (
    new BootstrapServiceRegistryImpl(
        new ClassLoaderServicePirilampo(Registro.class.getClassLoader()), 
        new LinkedHashSet<Integrator>()
    )
)
.applySettings(configuration.getProperties())
.addService(ClassLoaderService.class, new ClassLoaderServicePirilampo())
.build();

//this line throws ClassNotFoundException
sessionFactory = configuration.buildSessionFactory(serviceRegistry);    

我扩展了ClassLoaderServiceImpl以便记录所请求的类,并注意到从JUnit运行,从定义类的项目运行,它工作正常,我从服务获取类加载日志。但该服务从未收到过 如果我添加了以语音方式加载的注释类(来自GroovyClassLoader),请求同一个类。

最后一行抛出了以下错误:

17:06:49 ERROR [AssertionFailure] HHH000099: an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session): java.lang.ClassNotFoundException: implementacao.Registro
PersistentClass name cannot be converted into a Class
org.hibernate.AssertionFailure: PersistentClass name cannot be converted into a Class
    at org.hibernate.cfg.BinderHelper.getPropertyOverriddenByMapperOrMapsId(BinderHelper.java:817)
    at org.hibernate.cfg.AnnotationBinder.processElementAnnotations(AnnotationBinder.java:2169)
    at org.hibernate.cfg.AnnotationBinder.processIdPropertiesIfNotAlready(AnnotationBinder.java:963)
    at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:796)
    at org.hibernate.cfg.Configuration$MetadataSourceQueue.processAnnotatedClassesQueue(Configuration.java:3788)
    at org.hibernate.cfg.Configuration$MetadataSourceQueue.processMetadata(Configuration.java:3742)
    at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1410)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1844)
    at implementacao.ConsultaBase.createSessionFactory(ConsultaBase.java:64)
    at implementacao.ConsultaBase.consultar(ConsultaBase.java:92)
    at implementacao.ConsultaBase$consultar.call(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:112)
    at ConsultaBaseConector.run(ConsultaBaseConector.groovy:6)
    at groovy.util.GroovyScriptEngine.run(GroovyScriptEngine.java:551)
    at br.org.fplf.processo.maquinaexecucao.parser.ParserAtividadeAutomatica.executar(ParserAtividadeAutomatica.java:43)
    at br.org.fplf.processo.maquinaexecucao.MaquinaExecucao.executarAtividadeAutomatica(MaquinaExecucao.java:1050)
    at br.org.fplf.processo.maquinaexecucao.MaquinaExecucao.executarAtividadeFluxo(MaquinaExecucao.java:973)
    at br.org.fplf.processo.maquinaexecucao.MaquinaExecucao.executar(MaquinaExecucao.java:646)
    at br.org.fplf.processo.maquinaexecucao.MaquinaExecucao.run(MaquinaExecucao.java:368)
Caused by: java.lang.ClassNotFoundException: implementacao.Registro
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1702)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1547)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Unknown Source)
    at org.hibernate.annotations.common.util.ReflectHelper.classForName(ReflectHelper.java:60)
    at org.hibernate.annotations.common.reflection.java.JavaReflectionManager.classForName(JavaReflectionManager.java:138)
    at org.hibernate.cfg.BinderHelper.getPropertyOverriddenByMapperOrMapsId(BinderHelper.java:813)
    ... 20 more

1 个答案:

答案 0 :(得分:2)

这对我有用:

Thread.currentThread().setContextClassLoader(DynamicallyLoadedClass.getClassLoader());      

示例:

URL file = ConsultaBase.class.getProtectionDomain().getCodeSource().getLocation()
    .toURI().resolve("hibernate.cfg.xml").toURL(); 

Configuration configuration = new Configuration()
    .addAnnotatedClass(Registro.class).configure(file);         

ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
    .applySettings(configuration.getProperties())
    .build();

Thread.currentThread().setContextClassLoader(Registro.class.getClassLoader());

sessionFactory = configuration.buildSessionFactory(serviceRegistry);