Refactored bootstrapping of JSR-352 base context
Spring Batch's implementation of JSR-352 previously relied on Spring's ContextSingletonBeanFactoryLocator. However, this has been removed in Spring 5 as a relic of older EJB based use cases. This commit now lazily bootstraps the base context on it's own when the first JsrJobOperator is requested. Resolves BATCH-2572
This commit is contained in:
@@ -48,7 +48,7 @@ allprojects {
|
||||
|
||||
environmentProperty = project.hasProperty('environment') ? getProperty('environment') : 'hsql'
|
||||
|
||||
springVersionDefault = '4.3.6.RELEASE'
|
||||
springVersionDefault = '5.0.0.M5'
|
||||
springVersion = project.hasProperty('springVersion') ? getProperty('springVersion') : springVersionDefault
|
||||
springRetryVersion = '1.2.0.RELEASE'
|
||||
springAmqpVersion = '1.5.6.RELEASE'
|
||||
@@ -842,5 +842,5 @@ or specify the Gradle property `TCK_HOME`, e.g: ./gradlew runTck -PTCK_HOME=/pat
|
||||
|
||||
task wrapper(type: Wrapper) {
|
||||
description = 'Generates gradlew[.bat] scripts'
|
||||
gradleVersion = '3.0'
|
||||
gradleVersion = '3.4'
|
||||
}
|
||||
|
||||
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,6 @@
|
||||
#Thu Sep 29 16:06:24 CDT 2016
|
||||
#Wed Mar 08 11:23:55 CST 2017
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-3.0-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-3.4-bin.zip
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
* Copyright 2013-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.
|
||||
@@ -26,7 +26,6 @@ import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Semaphore;
|
||||
|
||||
import javax.batch.operations.BatchRuntimeException;
|
||||
import javax.batch.operations.JobExecutionAlreadyCompleteException;
|
||||
import javax.batch.operations.JobExecutionIsRunningException;
|
||||
@@ -46,6 +45,7 @@ import javax.batch.runtime.StepExecution;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.batch.core.BatchStatus;
|
||||
import org.springframework.batch.core.ExitStatus;
|
||||
import org.springframework.batch.core.Job;
|
||||
@@ -69,15 +69,13 @@ import org.springframework.batch.core.step.tasklet.TaskletStep;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.access.BeanFactoryLocator;
|
||||
import org.springframework.beans.factory.access.BeanFactoryReference;
|
||||
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.access.ContextSingletonBeanFactoryLocator;
|
||||
import org.springframework.context.support.GenericXmlApplicationContext;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
@@ -160,9 +158,8 @@ public class JsrJobOperator implements JobOperator, ApplicationContextAware, Ini
|
||||
* one if it has) to populate itself.
|
||||
*/
|
||||
public JsrJobOperator() {
|
||||
BeanFactoryLocator beanFactoryLocactor = ContextSingletonBeanFactoryLocator.getInstance();
|
||||
BeanFactoryReference ref = beanFactoryLocactor.useBeanFactory("baseContext");
|
||||
baseContext = (ApplicationContext) ref.getFactory();
|
||||
|
||||
this.baseContext = BaseContextHolder.getInstance().getContext();
|
||||
|
||||
baseContext.getAutowireCapableBeanFactory().autowireBeanProperties(this,
|
||||
AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false);
|
||||
@@ -805,4 +802,47 @@ public class JsrJobOperator implements JobOperator, ApplicationContextAware, Ini
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A singleton holder used to lazily bootstrap the base context used in JSR-352.
|
||||
*/
|
||||
protected static class BaseContextHolder {
|
||||
|
||||
private ApplicationContext context;
|
||||
|
||||
private static BaseContextHolder instance;
|
||||
|
||||
private BaseContextHolder() {
|
||||
synchronized (BaseContextHolder.class) {
|
||||
if(this.context == null) {
|
||||
String overrideContextLocation = System.getProperty("JSR-352-BASE-CONTEXT");
|
||||
|
||||
List<String> contextLocations = new ArrayList<>();
|
||||
|
||||
contextLocations.add("jsrBaseContext.xml");
|
||||
|
||||
if(overrideContextLocation != null) {
|
||||
contextLocations.add(overrideContextLocation);
|
||||
}
|
||||
|
||||
this.context = new GenericXmlApplicationContext(
|
||||
contextLocations.toArray(new String[contextLocations.size()]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static BaseContextHolder getInstance() {
|
||||
synchronized (BaseContextHolder.class) {
|
||||
if(instance == null) {
|
||||
instance = new BaseContextHolder();
|
||||
}
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
public ApplicationContext getContext() {
|
||||
return this.context;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
* Copyright 2013-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.
|
||||
@@ -15,20 +15,19 @@
|
||||
*/
|
||||
package org.springframework.batch.core.jsr.configuration.xml;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.batch.api.Batchlet;
|
||||
import javax.batch.runtime.JobExecution;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.Test;
|
||||
import org.w3c.dom.Document;
|
||||
import org.xml.sax.ErrorHandler;
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
import org.springframework.batch.core.jsr.AbstractJsrTestCase;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.xml.DefaultDocumentLoader;
|
||||
@@ -37,9 +36,10 @@ import org.springframework.beans.factory.xml.DocumentLoader;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.util.xml.SimpleSaxErrorHandler;
|
||||
import org.w3c.dom.Document;
|
||||
import org.xml.sax.ErrorHandler;
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -64,7 +64,7 @@ public class JsrBeanDefinitionDocumentReaderTests extends AbstractJsrTestCase {
|
||||
|
||||
JsrXmlApplicationContext applicationContext = new JsrXmlApplicationContext(jobParameters);
|
||||
applicationContext.setValidating(false);
|
||||
applicationContext.load(new ClassPathResource("baseContext.xml"),
|
||||
applicationContext.load(new ClassPathResource("jsrBaseContext.xml"),
|
||||
new ClassPathResource("/META-INF/batch.xml"),
|
||||
new ClassPathResource("/META-INF/batch-jobs/jsrPropertyPreparseTestJob.xml"));
|
||||
applicationContext.refresh();
|
||||
@@ -105,7 +105,7 @@ public class JsrBeanDefinitionDocumentReaderTests extends AbstractJsrTestCase {
|
||||
@SuppressWarnings("resource")
|
||||
JsrXmlApplicationContext applicationContext = new JsrXmlApplicationContext(jobParameters);
|
||||
applicationContext.setValidating(false);
|
||||
applicationContext.load(new ClassPathResource("baseContext.xml"),
|
||||
applicationContext.load(new ClassPathResource("jsrBaseContext.xml"),
|
||||
new ClassPathResource("/META-INF/batch.xml"),
|
||||
new ClassPathResource("/META-INF/batch-jobs/jsrPropertyPreparseTestJob.xml"));
|
||||
applicationContext.refresh();
|
||||
@@ -132,7 +132,7 @@ public class JsrBeanDefinitionDocumentReaderTests extends AbstractJsrTestCase {
|
||||
@SuppressWarnings("resource")
|
||||
JsrXmlApplicationContext applicationContext = new JsrXmlApplicationContext(jobParameters);
|
||||
applicationContext.setValidating(false);
|
||||
applicationContext.load(new ClassPathResource("baseContext.xml"),
|
||||
applicationContext.load(new ClassPathResource("jsrBaseContext.xml"),
|
||||
new ClassPathResource("/META-INF/batch.xml"),
|
||||
new ClassPathResource("/META-INF/batch-jobs/jsrPropertyPreparseTestJob.xml"));
|
||||
applicationContext.refresh();
|
||||
@@ -155,7 +155,7 @@ public class JsrBeanDefinitionDocumentReaderTests extends AbstractJsrTestCase {
|
||||
public void testGenerationOfBeanDefinitionsForMultipleReferences() throws Exception {
|
||||
JsrXmlApplicationContext applicationContext = new JsrXmlApplicationContext(new Properties());
|
||||
applicationContext.setValidating(false);
|
||||
applicationContext.load(new ClassPathResource("baseContext.xml"),
|
||||
applicationContext.load(new ClassPathResource("jsrBaseContext.xml"),
|
||||
new ClassPathResource("/META-INF/batch.xml"),
|
||||
new ClassPathResource("/META-INF/batch-jobs/jsrUniqueInstanceTests.xml"));
|
||||
applicationContext.refresh();
|
||||
@@ -209,7 +209,7 @@ public class JsrBeanDefinitionDocumentReaderTests extends AbstractJsrTestCase {
|
||||
public void testGenerationOfSpringBeanDefinitionsForMultipleReferences() {
|
||||
JsrXmlApplicationContext applicationContext = new JsrXmlApplicationContext(new Properties());
|
||||
applicationContext.setValidating(false);
|
||||
applicationContext.load(new ClassPathResource("baseContext.xml"),
|
||||
applicationContext.load(new ClassPathResource("jsrBaseContext.xml"),
|
||||
new ClassPathResource("/META-INF/batch-jobs/jsrSpringInstanceTests.xml"));
|
||||
|
||||
applicationContext.refresh();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
* Copyright 2013-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.
|
||||
@@ -15,24 +15,12 @@
|
||||
*/
|
||||
package org.springframework.batch.core.jsr.launch;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.batch.api.AbstractBatchlet;
|
||||
import javax.batch.api.Batchlet;
|
||||
import javax.batch.operations.JobExecutionIsRunningException;
|
||||
@@ -68,7 +56,6 @@ import org.springframework.batch.core.repository.JobRepository;
|
||||
import org.springframework.batch.core.step.JobRepositorySupport;
|
||||
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.context.access.ContextSingletonBeanFactoryLocator;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -79,6 +66,14 @@ import org.springframework.core.task.SyncTaskExecutor;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class JsrJobOperatorTests extends AbstractJsrTestCase {
|
||||
|
||||
private JobOperator jsrJobOperator;
|
||||
@@ -91,7 +86,6 @@ public class JsrJobOperatorTests extends AbstractJsrTestCase {
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
resetBaseContext();
|
||||
|
||||
MockitoAnnotations.initMocks(this);
|
||||
parameterConverter = new JobParametersConverterSupport();
|
||||
@@ -137,6 +131,8 @@ public class JsrJobOperatorTests extends AbstractJsrTestCase {
|
||||
public void testCustomBaseContextJsrCompliant() throws Exception {
|
||||
System.setProperty("JSR-352-BASE-CONTEXT", "META-INF/alternativeJsrBaseContext.xml");
|
||||
|
||||
ReflectionTestUtils.setField(JsrJobOperator.BaseContextHolder.class, "instance", null);
|
||||
|
||||
JobOperator jobOperator = BatchRuntime.getJobOperator();
|
||||
|
||||
Object transactionManager = ReflectionTestUtils.getField(jobOperator, "transactionManager");
|
||||
@@ -175,17 +171,6 @@ public class JsrJobOperatorTests extends AbstractJsrTestCase {
|
||||
System.getProperties().remove("JSR-352-BASE-CONTEXT");
|
||||
}
|
||||
|
||||
private void resetBaseContext() throws NoSuchFieldException, IllegalAccessException {
|
||||
Field instancesField = ContextSingletonBeanFactoryLocator.class.getDeclaredField("instances");
|
||||
instancesField.setAccessible(true);
|
||||
|
||||
Field instancesModifiers = Field.class.getDeclaredField("modifiers");
|
||||
instancesModifiers.setAccessible(true);
|
||||
instancesModifiers.setInt(instancesField, instancesField.getModifiers() & ~Modifier.FINAL);
|
||||
|
||||
instancesField.set(null, new HashMap());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultTaskExecutor() throws Exception {
|
||||
JsrJobOperator jsrJobOperatorImpl = (JsrJobOperator) jsrJobOperator;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
* Copyright 2013-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.
|
||||
@@ -15,24 +15,23 @@
|
||||
*/
|
||||
package org.springframework.batch.core.jsr.step;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.batch.core.explore.JobExplorer;
|
||||
import org.springframework.batch.core.jsr.AbstractJsrTestCase;
|
||||
import org.springframework.beans.factory.access.BeanFactoryLocator;
|
||||
import org.springframework.beans.factory.access.BeanFactoryReference;
|
||||
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.access.ContextSingletonBeanFactoryLocator;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import javax.batch.api.Decider;
|
||||
import javax.batch.runtime.BatchRuntime;
|
||||
import javax.batch.runtime.BatchStatus;
|
||||
import javax.batch.runtime.JobExecution;
|
||||
import javax.batch.runtime.StepExecution;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.batch.core.explore.JobExplorer;
|
||||
import org.springframework.batch.core.jsr.AbstractJsrTestCase;
|
||||
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.GenericXmlApplicationContext;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
@@ -47,9 +46,7 @@ public class DecisionStepTests extends AbstractJsrTestCase {
|
||||
StepExecutionCountingDecider.previousStepCount = 0;
|
||||
|
||||
if(jobExplorer == null) {
|
||||
BeanFactoryLocator beanFactoryLocactor = ContextSingletonBeanFactoryLocator.getInstance();
|
||||
BeanFactoryReference ref = beanFactoryLocactor.useBeanFactory("baseContext");
|
||||
baseContext = (ApplicationContext) ref.getFactory();
|
||||
baseContext = new GenericXmlApplicationContext("jsrBaseContext.xml");
|
||||
|
||||
baseContext.getAutowireCapableBeanFactory().autowireBeanProperties(this,
|
||||
AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, false);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2009 the original author or authors.
|
||||
* Copyright 2009-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.
|
||||
@@ -15,19 +15,20 @@
|
||||
*/
|
||||
package org.springframework.batch.core.partition.support;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.batch.item.ExecutionContext;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.UrlResource;
|
||||
import org.springframework.core.io.support.ResourceArrayPropertyEditor;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class MultiResourcePartitionerTests {
|
||||
|
||||
private MultiResourcePartitioner partitioner = new MultiResourcePartitioner();
|
||||
@@ -35,7 +36,7 @@ public class MultiResourcePartitionerTests {
|
||||
@Before
|
||||
public void setUp() {
|
||||
ResourceArrayPropertyEditor editor = new ResourceArrayPropertyEditor();
|
||||
editor.setAsText("classpath:baseContext.xml");
|
||||
editor.setAsText("classpath:jsrBaseContext.xml");
|
||||
partitioner.setResources((Resource[]) editor.getValue());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-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.
|
||||
@@ -73,14 +73,14 @@ import org.springframework.util.MethodInvoker;
|
||||
* <p>
|
||||
* The connection returned will be a close-suppressing proxy instead of the
|
||||
* physical {@link Connection}. Be aware that you will not be able to cast this
|
||||
* to a native <code>OracleConnection</code> or the like anymore; you need to
|
||||
* use a {@link org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor}.
|
||||
* to a native <code>OracleConnection</code> or the like anymore; you'd be required to use
|
||||
* {@link java.sql.Connection#unwrap(Class)}.
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
* @see #getConnection()
|
||||
* @see java.sql.Connection#close()
|
||||
* @see DataSourceUtils#releaseConnection
|
||||
* @see org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor
|
||||
* @see java.sql.Connection#unwrap(Class)
|
||||
* @since 2.0
|
||||
*/
|
||||
public class ExtendedConnectionDataSourceProxy implements SmartDataSource, InitializingBean {
|
||||
|
||||
Reference in New Issue
Block a user