Avoid ClassNotFoundException caused by areturn verification

The verifier's type checker is required to check that a type returned
from a method (an areturn instruction) is assignable to the method's
declared return type. When the return type is an interface, the JLS
states that it should be treated as java.lang.Object. This means that
no analysis of the type being returned is required and verification
passes. When the return type is a class, the type being returned must
be analyzed to ensure that it is compatible. This analysis causes the
return type to be loaded during verification.

Prior to this commit, BasicBatchConfigurer's
createAppropriateTransactionManager method had a return type of
AbstractPlatformTransactionManager and a branch that could return
a JpaTransactionManager. This caused the verifier to attempt to load
JpaTransactionManager so that it could check that it was assignable
to AbstractPlatformTransactionManager. This would fail when
spring-orm is not on the classpath as JpaTransactionManager could not
be loaded.

This commit updates BasicBatchConfigurer to change the return type
of createAppropriateTransactionManager so that it returns a
PlatformTransactionManager which is an interface. As described above,
this relaxes the verification of any areturn instructions in the
method and, in this particular case stops the verifier from trying to
load JpaTransactionManager.

Closes gh-8181
This commit is contained in:
Andy Wilkinson 2017-02-13 12:18:25 +00:00
parent bd6d1b74c0
commit e0b355d313

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2016 the original author or authors.
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -34,7 +34,6 @@ import org.springframework.boot.autoconfigure.transaction.TransactionManagerCust
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.support.AbstractPlatformTransactionManager;
import org.springframework.util.StringUtils;
/**
@ -162,14 +161,14 @@ public class BasicBatchConfigurer implements BatchConfigurer {
}
protected PlatformTransactionManager createTransactionManager() {
AbstractPlatformTransactionManager transactionManager = createAppropriateTransactionManager();
PlatformTransactionManager transactionManager = createAppropriateTransactionManager();
if (this.transactionManagerCustomizers != null) {
this.transactionManagerCustomizers.customize(transactionManager);
}
return transactionManager;
}
private AbstractPlatformTransactionManager createAppropriateTransactionManager() {
private PlatformTransactionManager createAppropriateTransactionManager() {
if (this.entityManagerFactory != null) {
return new JpaTransactionManager(this.entityManagerFactory);
}