From ef621c9271186047f895a387c7f710f5998a86aa Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Mon, 22 Dec 2014 21:28:11 -0800 Subject: [PATCH] Protect against NoClassDefFoundError on WAS Update HibernateJpaAutoConfiguration to catch NoClassDefFoundError when setting the JTA_PLATFORM. The exception can occur when running on WAS since it ships with Hibernate 4.2 and SpringJtaPlatform extends from AbstractJtaPlatform which is not present. The exception is now ignored if a JDNI environment is available, otherwise it is re-thrown. Fixes gh-2218 --- .../jpa/HibernateJpaAutoConfiguration.java | 37 ++++++++++++++++++- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.java index b78e8dfab9..6c6cfe009a 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.java @@ -22,6 +22,8 @@ import java.util.Map; import javax.persistence.EntityManager; import javax.sql.DataSource; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -38,6 +40,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.core.type.AnnotatedTypeMetadata; +import org.springframework.jndi.JndiLocatorDelegate; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.vendor.AbstractJpaVendorAdapter; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; @@ -59,6 +62,9 @@ import org.springframework.util.ClassUtils; @AutoConfigureAfter({ DataSourceAutoConfiguration.class, JtaAutoConfiguration.class }) public class HibernateJpaAutoConfiguration extends JpaBaseConfiguration { + private static final Log logger = LogFactory + .getLog(HibernateJpaAutoConfiguration.class); + private static final String JTA_PLATFORM = "hibernate.transaction.jta.platform"; /** @@ -98,14 +104,41 @@ public class HibernateJpaAutoConfiguration extends JpaBaseConfiguration { throws LinkageError { JtaTransactionManager jtaTransactionManager = getJtaTransactionManager(); if (jtaTransactionManager != null) { - vendorProperties.put(JTA_PLATFORM, new SpringJtaPlatform( - jtaTransactionManager)); + try { + vendorProperties.put(JTA_PLATFORM, new SpringJtaPlatform( + jtaTransactionManager)); + } + catch (NoClassDefFoundError ex) { + // Can happen if Hibernate 4.2 is used (for example on WAS) + if (isUsingJndi()) { + // Assume that we are not using a stand-alone transaction manager + // and Hibernate will use JNDI + if (logger.isDebugEnabled()) { + logger.debug("Unable to set Hibernate JTA platform : " + + ex.getMessage()); + } + } + else { + throw new IllegalStateException("Unable to set Hibernate JTA " + + "platform, are you using the correct " + + "version of hibernate?", ex); + } + } } else { vendorProperties.put(JTA_PLATFORM, getNoJtaPlatformManager()); } } + private boolean isUsingJndi() { + try { + return JndiLocatorDelegate.isDefaultJndiEnvironmentAvailable(); + } + catch (Error ex) { + return false; + } + } + private Object getNoJtaPlatformManager() { for (String noJtaPlatformClass : NO_JTA_PLATFORM_CLASSES) { try {