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
This commit is contained in:
Phillip Webb
2014-12-22 21:28:11 -08:00
parent fd97c7553c
commit ef621c9271

View File

@@ -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 {