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:
Michael Minella
2017-03-08 17:06:29 -06:00
parent 342d27bc1e
commit a6c4dacbbe
9 changed files with 101 additions and 78 deletions

View File

@@ -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();

View File

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

View File

@@ -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);

View File

@@ -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());
}