java.lang.ClassCircularityError: org/apache/log4j/spi/ThrowableInformation

Spring JIRA | Andrei Ivanov | 10 months ago
  1. 0

    Trying to upgrade Hibernate from 4.3.x to 5.0 throws this nice exception: {noformat} 25-Jan-2016 13:34:10.985 SEVERE [localhost-startStop-2] org.apache.catalina.core.StandardContext.listenerStop Exception sending context destroyed event to listener instance of class org.springframework.web.context.ContextLoaderListener java.lang.ClassCircularityError: org/apache/log4j/spi/ThrowableInformation at org.apache.log4j.spi.LoggingEvent.<init>(LoggingEvent.java:165) at org.apache.log4j.Category.forcedLog(Category.java:391) at org.apache.log4j.Category.log(Category.java:856) at org.slf4j.impl.Log4jLoggerAdapter.log(Log4jLoggerAdapter.java:595) at org.apache.commons.logging.impl.SLF4JLocationAwareLog.error(SLF4JLocationAwareLog.java:216) at org.springframework.orm.jpa.persistenceunit.ClassFileTransformerAdapter.transform(ClassFileTransformerAdapter.java:66) at org.springframework.instrument.classloading.WeavingTransformer.transformIfNecessary(WeavingTransformer.java:95) at org.springframework.instrument.classloading.WeavingTransformer.transformIfNecessary(WeavingTransformer.java:78) at org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader.findResourceInternal(TomcatInstrumentableClassLoader.java:127) at org.apache.catalina.loader.WebappClassLoaderBase.findClassInternal(WebappClassLoaderBase.java:2427) at org.apache.catalina.loader.WebappClassLoaderBase.findClass(WebappClassLoaderBase.java:860) at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1302) at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1167) at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:963) at org.springframework.context.support.AbstractApplicationContext.close(AbstractApplicationContext.java:934) at org.springframework.web.context.ContextLoader.closeWebApplicationContext(ContextLoader.java:583) at org.springframework.web.context.ContextLoaderListener.contextDestroyed(ContextLoaderListener.java:116) at org.apache.catalina.core.StandardContext.listenerStop(StandardContext.java:4859) at org.apache.catalina.core.StandardContext.stopInternal(StandardContext.java:5478) at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:232) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:160) at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:725) at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:701) at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:717) at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:945) at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1795) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) {noformat} It hides the actual {{ClassCircularityError}}, thrown here: {noformat} EnhancingClassTransformerImpl.transform(ClassLoader, String, Class<?>, ProtectionDomain, byte[]) line: 44 ClassFileTransformerAdapter.transform(ClassLoader, String, Class<?>, ProtectionDomain, byte[]) line: 56 WeavingTransformer.transformIfNecessary(String, String, byte[], ProtectionDomain) line: 95 WeavingTransformer.transformIfNecessary(String, byte[]) line: 78 TomcatInstrumentableClassLoader.findResourceInternal(String, String, boolean) line: 127 TomcatInstrumentableClassLoader(WebappClassLoaderBase).findClassInternal(String) line: 2427 TomcatInstrumentableClassLoader(WebappClassLoaderBase).findClass(String) line: 860 TomcatInstrumentableClassLoader(WebappClassLoaderBase).loadClass(String, boolean) line: 1302 TomcatInstrumentableClassLoader(WebappClassLoaderBase).loadClass(String) line: 1167 EnhancingClassTransformerImpl.transform(ClassLoader, String, Class<?>, ProtectionDomain, byte[]) line: 44 ClassFileTransformerAdapter.transform(ClassLoader, String, Class<?>, ProtectionDomain, byte[]) line: 56 WeavingTransformer.transformIfNecessary(String, String, byte[], ProtectionDomain) line: 95 WeavingTransformer.transformIfNecessary(String, byte[]) line: 78 TomcatInstrumentableClassLoader.findResourceInternal(String, String, boolean) line: 127 TomcatInstrumentableClassLoader(WebappClassLoaderBase).findClassInternal(String) line: 2427 TomcatInstrumentableClassLoader(WebappClassLoaderBase).findClass(String) line: 860 TomcatInstrumentableClassLoader(WebappClassLoaderBase).loadClass(String, boolean) line: 1302 TomcatInstrumentableClassLoader(WebappClassLoaderBase).loadClass(String) line: 1167 MetadataBuildingProcess.handleTypes(MetadataBuildingOptions) line: 327 MetadataBuildingProcess.complete(ManagedResources, MetadataBuildingOptions) line: 111 EntityManagerFactoryBuilderImpl.metadata() line: 847 EntityManagerFactoryBuilderImpl.build() line: 874 SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(PersistenceUnitInfo, Map) line: 60 LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory() line: 343 LocalContainerEntityManagerFactoryBean(AbstractEntityManagerFactoryBean).afterPropertiesSet() line: 318 DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).invokeInitMethods(String, Object, RootBeanDefinition) line: 1637 DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).initializeBean(String, Object, RootBeanDefinition) line: 1574 DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).doCreateBean(String, RootBeanDefinition, Object[]) line: 545 DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).createBean(String, RootBeanDefinition, Object[]) line: 482 AbstractBeanFactory$1.getObject() line: 306 DefaultListableBeanFactory(DefaultSingletonBeanRegistry).getSingleton(String, ObjectFactory<?>) line: 230 DefaultListableBeanFactory(AbstractBeanFactory).doGetBean(String, Class<T>, Object[], boolean) line: 302 DefaultListableBeanFactory(AbstractBeanFactory).getBean(String) line: 197 XmlWebApplicationContext(AbstractApplicationContext).getBean(String) line: 1054 XmlWebApplicationContext(AbstractApplicationContext).finishBeanFactoryInitialization(ConfigurableListableBeanFactory) line: 829 XmlWebApplicationContext(AbstractApplicationContext).refresh() line: 538 ContextLoaderListener(ContextLoader).configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext, ServletContext) line: 446 ContextLoaderListener(ContextLoader).initWebApplicationContext(ServletContext) line: 328 ContextLoaderListener.contextInitialized(ServletContextEvent) line: 107 StandardContext.listenerStart() line: 4812 StandardContext.startInternal() line: 5255 StandardContext(LifecycleBase).start() line: 150 StandardHost(ContainerBase).addChildInternal(Container) line: 725 StandardHost(ContainerBase).addChild(Container) line: 701 StandardHost.addChild(Container) line: 717 HostConfig.deployWAR(ContextName, File) line: 945 HostConfig$DeployWar.run() line: 1795 Executors$RunnableAdapter<T>.call() line: 511 FutureTask<V>.run() line: 266 ThreadPoolExecutor.runWorker(ThreadPoolExecutor$Worker) line: 1142 ThreadPoolExecutor$Worker.run() line: 617 Thread.run() line: 745 {noformat} MetadataBuildingProcess.handleTypes(MetadataBuildingOptions) line: 327 -> triggers loading of {{org.hibernate.type.BasicTypeRegistry}} 1st. call to EnhancingClassTransformerImpl.transform(ClassLoader, String, Class<?>, ProtectionDomain, byte[]) line: 44 triggers the loading of {{org.hibernate.bytecode.enhance.spi.Enhancer}} 2nd. call triggers the {{ClassCircularityError}} Investigating the issue, I see that {{org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl}} calls {{persistenceUnit.getTempClassLoader()}}, which ends up in {{org.springframework.instrument.classloading.ReflectiveLoadTimeWeaver#getThrowawayClassLoader}}, invoking {{org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader#getThrowawayClassLoader}}. In theory, this should handle this scenario. There are 2 problems here: # It returns {{org.apache.catalina.loader.WebappClassLoader}}, which is not a {{DecoratingClassLoader}}, so the exclude package ({{org.hibernate}}) is not set: {{SpringPersistenceUnitInfo#getNewTempClassLoader}} {code:java} public ClassLoader getNewTempClassLoader() { ClassLoader tcl = (this.loadTimeWeaver != null ? this.loadTimeWeaver.getThrowawayClassLoader() : new SimpleThrowawayClassLoader(this.classLoader)); String packageToExclude = getPersistenceProviderPackageName(); if (packageToExclude != null && tcl instanceof DecoratingClassLoader) { ((DecoratingClassLoader) tcl).excludePackage(packageToExclude); } return tcl; } {code} Even if it did, just {{org.hibernate}} wouldn't be enough here. # This temp classloader is no longer used when the error occurs {{EntityManagerFactoryBuilderImpl}}, on line 227, pushes the class transformer but 3 lines after (230) it sets the temp classloader to null. After this, {{EntityManagerFactoryBuilderImpl#build}} is called, and that triggers the error. Now for the workaround. Inspired by the {{AspectJClassBypassingClassFileTransformer}}, I've created my own: {code:java} public class HibernateClassBypassingLoadTimeWeaver implements LoadTimeWeaver { private final LoadTimeWeaver loadTimeWeaver; public HibernateClassBypassingLoadTimeWeaver(LoadTimeWeaver loadTimeWeaver) { Assert.notNull(loadTimeWeaver); this.loadTimeWeaver = loadTimeWeaver; } @Override public ClassLoader getInstrumentableClassLoader() { return loadTimeWeaver.getInstrumentableClassLoader(); } @Override public ClassLoader getThrowawayClassLoader() { return loadTimeWeaver.getThrowawayClassLoader(); } @Override public void addTransformer(ClassFileTransformer transformer) { loadTimeWeaver.addTransformer(new HibernateClassBypassingClassFileTransformer(transformer)); } /** * ClassFileTransformer decorator that suppresses processing of Hibernate * classes in order to avoid potential LinkageErrors. * @see org.springframework.context.annotation.LoadTimeWeavingConfiguration */ private static class HibernateClassBypassingClassFileTransformer implements ClassFileTransformer { private static final Logger LOGGER = LoggerFactory.getLogger(HibernateClassBypassingClassFileTransformer.class); private final ClassFileTransformer delegate; public HibernateClassBypassingClassFileTransformer(ClassFileTransformer delegate) { this.delegate = delegate; } @Override public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { if (className.startsWith("org.hibernate") || className.startsWith("org/hibernate") || className.startsWith("javassist")) { LOGGER.trace("Bypassing class: {}", className); return classfileBuffer; } return this.delegate.transform(loader, className, classBeingRedefined, protectionDomain, classfileBuffer); } } {code} As you can see in the code, ignoring just the Hibernate classes isn't enough, the Javassist classes must also be ignored. The problem with the workaround so far is that it cannot injected: {code:xml} <context:load-time-weaver /> <bean id="testEmf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="testDS" /> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" /> </property> <!-- this is normally initialized from the jpaVendorAdapter in afterPropertiesSet(), but it is needed earlier by the post-processor --> <property name="jpaDialect"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" /> </property> <property name="persistenceUnitName" value="testPU" /> <property name="jpaPropertyMap"> <map> <entry key="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" /> <entry key="hibernate.enable_lazy_load_no_trans" value="true" /> <!-- this deprecated setting enables all 3 new setting following --> <entry key="hibernate.ejb.use_class_enhancer" value="true" /> <!-- <entry key="hibernate.enhancer.enableDirtyTracking" value="true" /> <entry key="hibernate.enhancer.enableLazyInitialization" value="true" /> <entry key="hibernate.enhancer.enableAssociationManagement" value="true" /> --> <entry key="hibernate.id.new_generator_mappings" value="false" /> </map> </property> <property name="packagesToScan"> <list> <value>org.springframework.issues.entity</value> </list> </property> <property name="loadTimeWeaver"> <bean class="org.springframework.issues.hibernate.HibernateClassBypassingLoadTimeWeaver"> <constructor-arg ref="loadTimeWeaver" /> </bean> </property> </bean> {code} My LTW initially gets injected, but then the {{LoadTimeWeaverAwareProcessor}} comes along and injects back the original LTW ({{DefaultContextLoadTimeWeaver}}). I even tried with a {{DefaultPersistenceUnitManager}}, but that also implements {{LoadTimeWeaverAware}}. So, to get my LTW injected, I've created my own processor: {code:java} public class HibernateLoadTimeWeaverAwareProcessor implements BeanPostProcessor { private static final Logger LOGGER = LoggerFactory.getLogger(HibernateLoadTimeWeaverAwareProcessor.class); private final LoadTimeWeaver loadTimeWeaver; public HibernateLoadTimeWeaverAwareProcessor(LoadTimeWeaver loadTimeWeaver) { this.loadTimeWeaver = new HibernateClassBypassingLoadTimeWeaver(loadTimeWeaver); } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof LoadTimeWeaverAware && bean instanceof EntityManagerFactoryInfo) { JpaDialect jpaDialect = ((EntityManagerFactoryInfo) bean).getJpaDialect(); boolean isHibernate = jpaDialect instanceof HibernateJpaDialect; LOGGER.info("EMF {} has Hibernate dialect: {}", bean, isHibernate); if (isHibernate) { LOGGER.info("Injecting custom LTW: {}", loadTimeWeaver); ((LoadTimeWeaverAware) bean).setLoadTimeWeaver(loadTimeWeaver); } } return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; } } {code} This finally makes it run. So, did I miss something in the configuration? Is this supposed to run using standard Spring configuration? Or maybe Hibernate + bytecode enhancement wasn't tested thoroughly? The app is running inside a Tomcat 8.0.30 with LTW active.

    Spring JIRA | 10 months ago | Andrei Ivanov
    java.lang.ClassCircularityError: org/apache/log4j/spi/ThrowableInformation
  2. 0

    Trying to upgrade Hibernate from 4.3.x to 5.0 throws this nice exception: {noformat} 25-Jan-2016 13:34:10.985 SEVERE [localhost-startStop-2] org.apache.catalina.core.StandardContext.listenerStop Exception sending context destroyed event to listener instance of class org.springframework.web.context.ContextLoaderListener java.lang.ClassCircularityError: org/apache/log4j/spi/ThrowableInformation at org.apache.log4j.spi.LoggingEvent.<init>(LoggingEvent.java:165) at org.apache.log4j.Category.forcedLog(Category.java:391) at org.apache.log4j.Category.log(Category.java:856) at org.slf4j.impl.Log4jLoggerAdapter.log(Log4jLoggerAdapter.java:595) at org.apache.commons.logging.impl.SLF4JLocationAwareLog.error(SLF4JLocationAwareLog.java:216) at org.springframework.orm.jpa.persistenceunit.ClassFileTransformerAdapter.transform(ClassFileTransformerAdapter.java:66) at org.springframework.instrument.classloading.WeavingTransformer.transformIfNecessary(WeavingTransformer.java:95) at org.springframework.instrument.classloading.WeavingTransformer.transformIfNecessary(WeavingTransformer.java:78) at org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader.findResourceInternal(TomcatInstrumentableClassLoader.java:127) at org.apache.catalina.loader.WebappClassLoaderBase.findClassInternal(WebappClassLoaderBase.java:2427) at org.apache.catalina.loader.WebappClassLoaderBase.findClass(WebappClassLoaderBase.java:860) at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1302) at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1167) at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:963) at org.springframework.context.support.AbstractApplicationContext.close(AbstractApplicationContext.java:934) at org.springframework.web.context.ContextLoader.closeWebApplicationContext(ContextLoader.java:583) at org.springframework.web.context.ContextLoaderListener.contextDestroyed(ContextLoaderListener.java:116) at org.apache.catalina.core.StandardContext.listenerStop(StandardContext.java:4859) at org.apache.catalina.core.StandardContext.stopInternal(StandardContext.java:5478) at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:232) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:160) at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:725) at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:701) at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:717) at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:945) at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1795) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) {noformat} It hides the actual {{ClassCircularityError}}, thrown here: {noformat} EnhancingClassTransformerImpl.transform(ClassLoader, String, Class<?>, ProtectionDomain, byte[]) line: 44 ClassFileTransformerAdapter.transform(ClassLoader, String, Class<?>, ProtectionDomain, byte[]) line: 56 WeavingTransformer.transformIfNecessary(String, String, byte[], ProtectionDomain) line: 95 WeavingTransformer.transformIfNecessary(String, byte[]) line: 78 TomcatInstrumentableClassLoader.findResourceInternal(String, String, boolean) line: 127 TomcatInstrumentableClassLoader(WebappClassLoaderBase).findClassInternal(String) line: 2427 TomcatInstrumentableClassLoader(WebappClassLoaderBase).findClass(String) line: 860 TomcatInstrumentableClassLoader(WebappClassLoaderBase).loadClass(String, boolean) line: 1302 TomcatInstrumentableClassLoader(WebappClassLoaderBase).loadClass(String) line: 1167 EnhancingClassTransformerImpl.transform(ClassLoader, String, Class<?>, ProtectionDomain, byte[]) line: 44 ClassFileTransformerAdapter.transform(ClassLoader, String, Class<?>, ProtectionDomain, byte[]) line: 56 WeavingTransformer.transformIfNecessary(String, String, byte[], ProtectionDomain) line: 95 WeavingTransformer.transformIfNecessary(String, byte[]) line: 78 TomcatInstrumentableClassLoader.findResourceInternal(String, String, boolean) line: 127 TomcatInstrumentableClassLoader(WebappClassLoaderBase).findClassInternal(String) line: 2427 TomcatInstrumentableClassLoader(WebappClassLoaderBase).findClass(String) line: 860 TomcatInstrumentableClassLoader(WebappClassLoaderBase).loadClass(String, boolean) line: 1302 TomcatInstrumentableClassLoader(WebappClassLoaderBase).loadClass(String) line: 1167 MetadataBuildingProcess.handleTypes(MetadataBuildingOptions) line: 327 MetadataBuildingProcess.complete(ManagedResources, MetadataBuildingOptions) line: 111 EntityManagerFactoryBuilderImpl.metadata() line: 847 EntityManagerFactoryBuilderImpl.build() line: 874 SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(PersistenceUnitInfo, Map) line: 60 LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory() line: 343 LocalContainerEntityManagerFactoryBean(AbstractEntityManagerFactoryBean).afterPropertiesSet() line: 318 DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).invokeInitMethods(String, Object, RootBeanDefinition) line: 1637 DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).initializeBean(String, Object, RootBeanDefinition) line: 1574 DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).doCreateBean(String, RootBeanDefinition, Object[]) line: 545 DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).createBean(String, RootBeanDefinition, Object[]) line: 482 AbstractBeanFactory$1.getObject() line: 306 DefaultListableBeanFactory(DefaultSingletonBeanRegistry).getSingleton(String, ObjectFactory<?>) line: 230 DefaultListableBeanFactory(AbstractBeanFactory).doGetBean(String, Class<T>, Object[], boolean) line: 302 DefaultListableBeanFactory(AbstractBeanFactory).getBean(String) line: 197 XmlWebApplicationContext(AbstractApplicationContext).getBean(String) line: 1054 XmlWebApplicationContext(AbstractApplicationContext).finishBeanFactoryInitialization(ConfigurableListableBeanFactory) line: 829 XmlWebApplicationContext(AbstractApplicationContext).refresh() line: 538 ContextLoaderListener(ContextLoader).configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext, ServletContext) line: 446 ContextLoaderListener(ContextLoader).initWebApplicationContext(ServletContext) line: 328 ContextLoaderListener.contextInitialized(ServletContextEvent) line: 107 StandardContext.listenerStart() line: 4812 StandardContext.startInternal() line: 5255 StandardContext(LifecycleBase).start() line: 150 StandardHost(ContainerBase).addChildInternal(Container) line: 725 StandardHost(ContainerBase).addChild(Container) line: 701 StandardHost.addChild(Container) line: 717 HostConfig.deployWAR(ContextName, File) line: 945 HostConfig$DeployWar.run() line: 1795 Executors$RunnableAdapter<T>.call() line: 511 FutureTask<V>.run() line: 266 ThreadPoolExecutor.runWorker(ThreadPoolExecutor$Worker) line: 1142 ThreadPoolExecutor$Worker.run() line: 617 Thread.run() line: 745 {noformat} MetadataBuildingProcess.handleTypes(MetadataBuildingOptions) line: 327 -> triggers loading of {{org.hibernate.type.BasicTypeRegistry}} 1st. call to EnhancingClassTransformerImpl.transform(ClassLoader, String, Class<?>, ProtectionDomain, byte[]) line: 44 triggers the loading of {{org.hibernate.bytecode.enhance.spi.Enhancer}} 2nd. call triggers the {{ClassCircularityError}} Investigating the issue, I see that {{org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl}} calls {{persistenceUnit.getTempClassLoader()}}, which ends up in {{org.springframework.instrument.classloading.ReflectiveLoadTimeWeaver#getThrowawayClassLoader}}, invoking {{org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader#getThrowawayClassLoader}}. In theory, this should handle this scenario. There are 2 problems here: # It returns {{org.apache.catalina.loader.WebappClassLoader}}, which is not a {{DecoratingClassLoader}}, so the exclude package ({{org.hibernate}}) is not set: {{SpringPersistenceUnitInfo#getNewTempClassLoader}} {code:java} public ClassLoader getNewTempClassLoader() { ClassLoader tcl = (this.loadTimeWeaver != null ? this.loadTimeWeaver.getThrowawayClassLoader() : new SimpleThrowawayClassLoader(this.classLoader)); String packageToExclude = getPersistenceProviderPackageName(); if (packageToExclude != null && tcl instanceof DecoratingClassLoader) { ((DecoratingClassLoader) tcl).excludePackage(packageToExclude); } return tcl; } {code} Even if it did, just {{org.hibernate}} wouldn't be enough here. # This temp classloader is no longer used when the error occurs {{EntityManagerFactoryBuilderImpl}}, on line 227, pushes the class transformer but 3 lines after (230) it sets the temp classloader to null. After this, {{EntityManagerFactoryBuilderImpl#build}} is called, and that triggers the error. Now for the workaround. Inspired by the {{AspectJClassBypassingClassFileTransformer}}, I've created my own: {code:java} public class HibernateClassBypassingLoadTimeWeaver implements LoadTimeWeaver { private final LoadTimeWeaver loadTimeWeaver; public HibernateClassBypassingLoadTimeWeaver(LoadTimeWeaver loadTimeWeaver) { Assert.notNull(loadTimeWeaver); this.loadTimeWeaver = loadTimeWeaver; } @Override public ClassLoader getInstrumentableClassLoader() { return loadTimeWeaver.getInstrumentableClassLoader(); } @Override public ClassLoader getThrowawayClassLoader() { return loadTimeWeaver.getThrowawayClassLoader(); } @Override public void addTransformer(ClassFileTransformer transformer) { loadTimeWeaver.addTransformer(new HibernateClassBypassingClassFileTransformer(transformer)); } /** * ClassFileTransformer decorator that suppresses processing of Hibernate * classes in order to avoid potential LinkageErrors. * @see org.springframework.context.annotation.LoadTimeWeavingConfiguration */ private static class HibernateClassBypassingClassFileTransformer implements ClassFileTransformer { private static final Logger LOGGER = LoggerFactory.getLogger(HibernateClassBypassingClassFileTransformer.class); private final ClassFileTransformer delegate; public HibernateClassBypassingClassFileTransformer(ClassFileTransformer delegate) { this.delegate = delegate; } @Override public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { if (className.startsWith("org.hibernate") || className.startsWith("org/hibernate") || className.startsWith("javassist")) { LOGGER.trace("Bypassing class: {}", className); return classfileBuffer; } return this.delegate.transform(loader, className, classBeingRedefined, protectionDomain, classfileBuffer); } } {code} As you can see in the code, ignoring just the Hibernate classes isn't enough, the Javassist classes must also be ignored. The problem with the workaround so far is that it cannot injected: {code:xml} <context:load-time-weaver /> <bean id="testEmf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="testDS" /> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" /> </property> <!-- this is normally initialized from the jpaVendorAdapter in afterPropertiesSet(), but it is needed earlier by the post-processor --> <property name="jpaDialect"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" /> </property> <property name="persistenceUnitName" value="testPU" /> <property name="jpaPropertyMap"> <map> <entry key="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" /> <entry key="hibernate.enable_lazy_load_no_trans" value="true" /> <!-- this deprecated setting enables all 3 new setting following --> <entry key="hibernate.ejb.use_class_enhancer" value="true" /> <!-- <entry key="hibernate.enhancer.enableDirtyTracking" value="true" /> <entry key="hibernate.enhancer.enableLazyInitialization" value="true" /> <entry key="hibernate.enhancer.enableAssociationManagement" value="true" /> --> <entry key="hibernate.id.new_generator_mappings" value="false" /> </map> </property> <property name="packagesToScan"> <list> <value>org.springframework.issues.entity</value> </list> </property> <property name="loadTimeWeaver"> <bean class="org.springframework.issues.hibernate.HibernateClassBypassingLoadTimeWeaver"> <constructor-arg ref="loadTimeWeaver" /> </bean> </property> </bean> {code} My LTW initially gets injected, but then the {{LoadTimeWeaverAwareProcessor}} comes along and injects back the original LTW ({{DefaultContextLoadTimeWeaver}}). I even tried with a {{DefaultPersistenceUnitManager}}, but that also implements {{LoadTimeWeaverAware}}. So, to get my LTW injected, I've created my own processor: {code:java} public class HibernateLoadTimeWeaverAwareProcessor implements BeanPostProcessor { private static final Logger LOGGER = LoggerFactory.getLogger(HibernateLoadTimeWeaverAwareProcessor.class); private final LoadTimeWeaver loadTimeWeaver; public HibernateLoadTimeWeaverAwareProcessor(LoadTimeWeaver loadTimeWeaver) { this.loadTimeWeaver = new HibernateClassBypassingLoadTimeWeaver(loadTimeWeaver); } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof LoadTimeWeaverAware && bean instanceof EntityManagerFactoryInfo) { JpaDialect jpaDialect = ((EntityManagerFactoryInfo) bean).getJpaDialect(); boolean isHibernate = jpaDialect instanceof HibernateJpaDialect; LOGGER.info("EMF {} has Hibernate dialect: {}", bean, isHibernate); if (isHibernate) { LOGGER.info("Injecting custom LTW: {}", loadTimeWeaver); ((LoadTimeWeaverAware) bean).setLoadTimeWeaver(loadTimeWeaver); } } return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; } } {code} This finally makes it run. So, did I miss something in the configuration? Is this supposed to run using standard Spring configuration? Or maybe Hibernate + bytecode enhancement wasn't tested thoroughly? The app is running inside a Tomcat 8.0.30 with LTW active.

    Spring JIRA | 10 months ago | Andrei Ivanov
    java.lang.ClassCircularityError: org/apache/log4j/spi/ThrowableInformation
  3. 0

    Unable to use with Maven SDK

    GitHub | 8 months ago | pzrinscak
    java.lang.ClassCircularityError: org/apache/log4j/spi/ThrowableInformation
  4. Speed up your debug routine!

    Automated exception search integrated into your IDE

  5. 0

    jboss 4.0 support

    GitHub | 1 year ago | GoogleCodeExporter
    java.lang.ClassCircularityError: org/apache/log4j/spi/LoggingEvent

    Not finding the right solution?
    Take a tour to get the most out of Samebug.

    Tired of useless tips?

    Automated exception search integrated into your IDE

    Root Cause Analysis

    1. java.lang.ClassCircularityError

      org/apache/log4j/spi/ThrowableInformation

      at org.apache.log4j.spi.LoggingEvent.<init>()
    2. Apache Log4j
      Category.log
      1. org.apache.log4j.spi.LoggingEvent.<init>(LoggingEvent.java:165)
      2. org.apache.log4j.Category.forcedLog(Category.java:391)
      3. org.apache.log4j.Category.log(Category.java:856)
      3 frames
    3. SLF4J LOG4J-12 Binding
      Log4jLoggerAdapter.log
      1. org.slf4j.impl.Log4jLoggerAdapter.log(Log4jLoggerAdapter.java:595)
      1 frame
    4. Apache Commons Logging
      SLF4JLocationAwareLog.error
      1. org.apache.commons.logging.impl.SLF4JLocationAwareLog.error(SLF4JLocationAwareLog.java:216)
      1 frame
    5. Spring ORM
      ClassFileTransformerAdapter.transform
      1. org.springframework.orm.jpa.persistenceunit.ClassFileTransformerAdapter.transform(ClassFileTransformerAdapter.java:66)
      1 frame
    6. Spring Context
      WeavingTransformer.transformIfNecessary
      1. org.springframework.instrument.classloading.WeavingTransformer.transformIfNecessary(WeavingTransformer.java:95)
      2. org.springframework.instrument.classloading.WeavingTransformer.transformIfNecessary(WeavingTransformer.java:78)
      2 frames
    7. Spring Framework
      TomcatInstrumentableClassLoader.findResourceInternal
      1. org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader.findResourceInternal(TomcatInstrumentableClassLoader.java:127)
      1 frame
    8. Glassfish Core
      WebappClassLoaderBase.loadClass
      1. org.apache.catalina.loader.WebappClassLoaderBase.findClassInternal(WebappClassLoaderBase.java:2427)
      2. org.apache.catalina.loader.WebappClassLoaderBase.findClass(WebappClassLoaderBase.java:860)
      3. org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1302)
      4. org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1167)
      4 frames
    9. Spring Context
      AbstractApplicationContext.close
      1. org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:963)
      2. org.springframework.context.support.AbstractApplicationContext.close(AbstractApplicationContext.java:934)
      2 frames
    10. Spring
      ContextLoaderListener.contextDestroyed
      1. org.springframework.web.context.ContextLoader.closeWebApplicationContext(ContextLoader.java:583)
      2. org.springframework.web.context.ContextLoaderListener.contextDestroyed(ContextLoaderListener.java:116)
      2 frames
    11. Glassfish Core
      HostConfig$DeployWar.run
      1. org.apache.catalina.core.StandardContext.listenerStop(StandardContext.java:4859)
      2. org.apache.catalina.core.StandardContext.stopInternal(StandardContext.java:5478)
      3. org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:232)
      4. org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:160)
      5. org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:725)
      6. org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:701)
      7. org.apache.catalina.core.StandardHost.addChild(StandardHost.java:717)
      8. org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:945)
      9. org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1795)
      9 frames
    12. Java RT
      Thread.run
      1. java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
      2. java.util.concurrent.FutureTask.run(FutureTask.java:266)
      3. java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
      4. java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
      5. java.lang.Thread.run(Thread.java:745)
      5 frames