RESOLVED - issue BATCH-343: close() is called twice on ItemReaders/ItemWriters

http://jira.springframework.org/browse/BATCH-343

ItemStream implementations no longer implement DisposableBean
This commit is contained in:
robokaso
2008-02-06 14:20:21 +00:00
parent 242970dd29
commit 37cf297899
14 changed files with 195 additions and 249 deletions

View File

@@ -24,10 +24,10 @@ import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.StatelessSession;
import org.springframework.batch.io.Skippable;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ExecutionAttributes;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemStream;
import org.springframework.batch.item.reader.AbstractItemStreamItemReader;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
@@ -51,8 +51,7 @@ import org.springframework.util.StringUtils;
* @author Robert Kasanicky
* @author Dave Syer
*/
public class HibernateCursorItemReader extends AbstractItemStreamItemReader implements Skippable, InitializingBean,
DisposableBean {
public class HibernateCursorItemReader extends AbstractItemStreamItemReader implements Skippable, InitializingBean {
private static final String RESTART_DATA_ROW_NUMBER_KEY = ClassUtils.getShortName(HibernateCursorItemReader.class)
+ ".rowNumber";
@@ -148,10 +147,6 @@ public class HibernateCursorItemReader extends AbstractItemStreamItemReader impl
Assert.hasLength(queryString);
}
public void destroy() throws Exception {
close();
}
/**
* @param queryString HQL query string
*/
@@ -232,7 +227,8 @@ public class HibernateCursorItemReader extends AbstractItemStreamItemReader impl
return true;
}
/* (non-Javadoc)
/*
* (non-Javadoc)
* @see org.springframework.batch.item.stream.ItemStreamAdapter#mark(org.springframework.batch.item.ExecutionAttributes)
*/
public void mark() {
@@ -242,7 +238,8 @@ public class HibernateCursorItemReader extends AbstractItemStreamItemReader impl
}
}
/* (non-Javadoc)
/*
* (non-Javadoc)
* @see org.springframework.batch.item.stream.ItemStreamAdapter#reset(org.springframework.batch.item.ExecutionAttributes)
*/
public void reset() {

View File

@@ -30,10 +30,9 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.batch.io.Skippable;
import org.springframework.batch.io.support.AbstractTransactionalIoSource;
import org.springframework.batch.item.ExecutionAttributes;
import org.springframework.batch.item.ItemStream;
import org.springframework.batch.item.KeyedItemReader;
import org.springframework.batch.item.ExecutionAttributes;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.InvalidDataAccessResourceUsageException;
@@ -108,7 +107,7 @@ import org.springframework.util.StringUtils;
* @author Lucas Ward
* @author Peter Zozom
*/
public class JdbcCursorItemReader extends AbstractTransactionalIoSource implements KeyedItemReader, DisposableBean,
public class JdbcCursorItemReader extends AbstractTransactionalIoSource implements KeyedItemReader,
InitializingBean, ItemStream, Skippable {
private static Log log = LogFactory.getLog(JdbcCursorItemReader.class);
@@ -275,16 +274,6 @@ public class JdbcCursorItemReader extends AbstractTransactionalIoSource implemen
skipCount = 0;
}
/**
* Calls close to ensure that bean factories can close and always release
* resources.
*
* @see org.springframework.beans.factory.DisposableBean#destroy()
*/
public void destroy() throws Exception {
close();
}
// Check the result set is in synch with the currentRow attribute. This is
// important
// to ensure that the user hasn't modified the current row.

View File

@@ -19,10 +19,9 @@ import java.util.Iterator;
import java.util.List;
import org.springframework.batch.io.support.AbstractTransactionalIoSource;
import org.springframework.batch.item.ExecutionAttributes;
import org.springframework.batch.item.ItemStream;
import org.springframework.batch.item.KeyedItemReader;
import org.springframework.batch.item.ExecutionAttributes;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
@@ -48,9 +47,8 @@ import org.springframework.util.Assert;
* @author Lucas Ward
* @since 1.0
*/
public class DrivingQueryItemReader extends AbstractTransactionalIoSource
implements KeyedItemReader, InitializingBean,
DisposableBean, ItemStream {
public class DrivingQueryItemReader extends AbstractTransactionalIoSource implements KeyedItemReader, InitializingBean,
ItemStream {
private boolean initialized = false;
@@ -84,7 +82,7 @@ public class DrivingQueryItemReader extends AbstractTransactionalIoSource
* be called.
*
* @return next key in the list if not index is not at the last element,
* null otherwise.
* null otherwise.
*/
public Object read() {
if (!initialized) {
@@ -132,50 +130,37 @@ public class DrivingQueryItemReader extends AbstractTransactionalIoSource
* {@link BatchTransactionSynchronizationManager} in order to ensure it is
* notified about commits and rollbacks.
*
* @throws IllegalStateException
* if the keys list is null or initialized is true.
* @throws IllegalStateException if the keys list is null or initialized is
* true.
*/
public void open() {
Assert.state(keys == null || initialized,
"Cannot open an already opened input source"
+ ", call close() first.");
Assert.state(keys == null || initialized, "Cannot open an already opened input source"
+ ", call close() first.");
keys = keyGenerator.retrieveKeys();
keysIterator = keys.listIterator();
initialized = true;
}
/*
* (non-Javadoc)
*
* @see org.springframework.beans.factory.DisposableBean#destroy()
*/
public void destroy() throws Exception {
close();
}
/**
* Restore input source to previous state. If the input source has already
* been initialized before calling restore (meaning, read has been called)
* then an IllegalStateException will be thrown, since all input sources
* should be restored before being read from, otherwise already processed
* data could be returned. The {@link ExecutionAttributes} attempting to be restored from
* must have been obtained from the <strong>same input source as the one
* being restored from</strong> otherwise it is invalid.
* data could be returned. The {@link ExecutionAttributes} attempting to be
* restored from must have been obtained from the <strong>same input source
* as the one being restored from</strong> otherwise it is invalid.
*
* @throws IllegalArgumentException
* if restart data or it's properties is null.
* @throws IllegalStateException
* if the input source has already been initialized.
* @throws IllegalArgumentException if restart data or it's properties is
* null.
* @throws IllegalStateException if the input source has already been
* initialized.
*/
public final void restoreFrom(ExecutionAttributes data) {
Assert.notNull(data, "ExecutionAttributes must not be null.");
Assert.notNull(data.getProperties(),
"ExecutionAttributes properties must not be null.");
Assert.state(!initialized,
"Cannot restore when already intialized. Call"
+ " close() first before restore()");
Assert.notNull(data.getProperties(), "ExecutionAttributes properties must not be null.");
Assert.state(!initialized, "Cannot restore when already intialized. Call" + " close() first before restore()");
if (data.getProperties().size() == 0) {
return;
@@ -216,6 +201,7 @@ public class DrivingQueryItemReader extends AbstractTransactionalIoSource
/**
* Return the item itself (which is already a key).
*
* @see org.springframework.batch.item.ItemReader#getKey(java.lang.Object)
*/
public Object getKey(Object item) {
@@ -234,14 +220,18 @@ public class DrivingQueryItemReader extends AbstractTransactionalIoSource
return true;
}
/* (non-Javadoc)
/*
* (non-Javadoc)
*
* @see org.springframework.batch.io.support.AbstractTransactionalIoSource#mark(org.springframework.batch.item.ExecutionAttributes)
*/
public void mark() {
lastCommitIndex = currentIndex;
}
/* (non-Javadoc)
/*
* (non-Javadoc)
*
* @see org.springframework.batch.io.support.AbstractTransactionalIoSource#reset(org.springframework.batch.item.ExecutionAttributes)
*/
public void reset() {

View File

@@ -31,12 +31,11 @@ import java.util.Properties;
import org.springframework.batch.io.exception.BatchCriticalException;
import org.springframework.batch.io.exception.BatchEnvironmentException;
import org.springframework.batch.io.support.AbstractTransactionalIoSource;
import org.springframework.batch.item.ExecutionAttributes;
import org.springframework.batch.item.ItemStream;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.ExecutionAttributes;
import org.springframework.batch.item.StreamException;
import org.springframework.batch.item.writer.ItemTransformer;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.Resource;
import org.springframework.dao.DataAccessResourceFailureException;
@@ -59,7 +58,7 @@ import org.springframework.util.Assert;
* @author Dave Syer
*/
public class FlatFileItemWriter extends AbstractTransactionalIoSource implements ItemWriter, ItemStream,
InitializingBean, DisposableBean {
InitializingBean {
private static final String LINE_SEPARATOR = System.getProperty("line.separator");
@@ -198,22 +197,12 @@ public class FlatFileItemWriter extends AbstractTransactionalIoSource implements
* @see ResourceLifecycle#close()
*/
public void close() {
if (state!=null) {
if (state != null) {
getOutputState().close();
state = null;
}
}
/**
* Calls close to ensure that bean factories can close and always release
* resources.
*
* @see org.springframework.beans.factory.DisposableBean#destroy()
*/
public void destroy() throws Exception {
close();
}
/**
* Sets encoding for output template.
*/
@@ -269,7 +258,7 @@ public class FlatFileItemWriter extends AbstractTransactionalIoSource implements
// Returns object representing state.
private OutputState getOutputState() {
if (state==null) {
if (state == null) {
state = new OutputState();
}
return (OutputState) state;
@@ -549,14 +538,16 @@ public class FlatFileItemWriter extends AbstractTransactionalIoSource implements
return true;
}
/* (non-Javadoc)
/*
* (non-Javadoc)
* @see org.springframework.batch.io.support.AbstractTransactionalIoSource#mark(org.springframework.batch.item.ExecutionAttributes)
*/
public void mark() {
getOutputState().mark();
}
/* (non-Javadoc)
/*
* (non-Javadoc)
* @see org.springframework.batch.io.support.AbstractTransactionalIoSource#reset(org.springframework.batch.item.ExecutionAttributes)
*/
public void reset() {

View File

@@ -29,7 +29,6 @@ import org.springframework.batch.io.exception.BatchEnvironmentException;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemStream;
import org.springframework.batch.item.stream.ItemStreamAdapter;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.core.io.Resource;
import org.springframework.util.Assert;
@@ -56,8 +55,7 @@ import org.springframework.util.Assert;
* @author Dave Syer
* @author Rob Harrop
*/
public class ResourceLineReader extends ItemStreamAdapter implements LineReader, ItemReader,
DisposableBean {
public class ResourceLineReader extends ItemStreamAdapter implements LineReader, ItemReader {
private static final Collection DEFAULT_COMMENTS = Collections.singleton("#");
@@ -186,15 +184,6 @@ public class ResourceLineReader extends ItemStreamAdapter implements LineReader,
}
}
/**
* Calls close to ensure that bean factory releases all resources.
*
* @see org.springframework.beans.factory.DisposableBean#destroy()
*/
public void destroy() throws Exception {
close();
}
/**
* Getter for current line count (not the current number of lines returned).
*
@@ -203,7 +192,7 @@ public class ResourceLineReader extends ItemStreamAdapter implements LineReader,
public int getPosition() {
return getState().getCurrentLineCount();
}
/**
* Mark is supported as long as this {@link ItemStream} is used in a
* single-threaded environment. The state backing the mark is a single

View File

@@ -16,11 +16,10 @@ import org.springframework.batch.io.xml.stax.DefaultFragmentEventReader;
import org.springframework.batch.io.xml.stax.DefaultTransactionalEventReader;
import org.springframework.batch.io.xml.stax.FragmentEventReader;
import org.springframework.batch.io.xml.stax.TransactionalEventReader;
import org.springframework.batch.item.ExecutionAttributes;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemStream;
import org.springframework.batch.item.ExecutionAttributes;
import org.springframework.batch.item.reader.AbstractItemReader;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.Resource;
import org.springframework.dao.DataAccessResourceFailureException;
@@ -36,8 +35,8 @@ import org.springframework.util.Assert;
*
* @author Robert Kasanicky
*/
public class StaxEventItemReader extends AbstractItemReader implements ItemReader,
Skippable, ItemStream, InitializingBean, DisposableBean {
public class StaxEventItemReader extends AbstractItemReader implements ItemReader, Skippable, ItemStream,
InitializingBean {
public static final String READ_COUNT_STATISTICS_NAME = "StaxEventReaderItemReader.readCount";
@@ -90,7 +89,7 @@ public class StaxEventItemReader extends AbstractItemReader implements ItemReade
public void close() {
initialized = false;
if (fragmentReader==null && inputStream==null) {
if (fragmentReader == null && inputStream == null) {
return;
}
try {
@@ -132,8 +131,8 @@ public class StaxEventItemReader extends AbstractItemReader implements ItemReade
}
/**
* @param eventReaderDeserializer maps xml fragments corresponding to records
* to objects
* @param eventReaderDeserializer maps xml fragments corresponding to
* records to objects
*/
public void setFragmentDeserializer(EventReaderDeserializer eventReaderDeserializer) {
this.eventReaderDeserializer = eventReaderDeserializer;
@@ -186,7 +185,8 @@ public class StaxEventItemReader extends AbstractItemReader implements ItemReade
* Restores the input source for the given restart data by rereading and
* skipping the number of records stored in the {@link ExecutionAttributes}.
*
* @param ExecutionAttributes that holds the line count from the last commit.
* @param ExecutionAttributes that holds the line count from the last
* commit.
* @throws IllegalStateException if the ItemReader has already been
* initialized or if the number of records to read and skip exceeds the
* available records.
@@ -247,10 +247,6 @@ public class StaxEventItemReader extends AbstractItemReader implements ItemReade
}
}
public void destroy() throws Exception {
close();
}
/**
* Mark is supported as long as this {@link ItemStream} is used in a
* single-threaded environment. The state backing the mark is a single
@@ -263,7 +259,8 @@ public class StaxEventItemReader extends AbstractItemReader implements ItemReade
return true;
}
/* (non-Javadoc)
/*
* (non-Javadoc)
* @see org.springframework.batch.item.ItemStream#mark(org.springframework.batch.item.ExecutionAttributes)
*/
public void mark() {
@@ -272,7 +269,8 @@ public class StaxEventItemReader extends AbstractItemReader implements ItemReade
skipRecords = new ArrayList();
}
/* (non-Javadoc)
/*
* (non-Javadoc)
* @see org.springframework.batch.item.ItemStream#reset(org.springframework.batch.item.ExecutionAttributes)
*/
public void reset() {
@@ -281,5 +279,4 @@ public class StaxEventItemReader extends AbstractItemReader implements ItemReade
fragmentReader.reset();
}
}

View File

@@ -15,11 +15,10 @@ import javax.xml.stream.XMLStreamException;
import org.springframework.batch.io.support.FileUtils;
import org.springframework.batch.io.xml.stax.NoStartEndDocumentStreamWriter;
import org.springframework.batch.item.ExecutionAttributes;
import org.springframework.batch.item.ItemStream;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.ExecutionAttributes;
import org.springframework.batch.item.StreamException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.Resource;
import org.springframework.dao.DataAccessResourceFailureException;
@@ -36,7 +35,7 @@ import org.springframework.util.CollectionUtils;
* @author Peter Zozom
*
*/
public class StaxEventItemWriter implements ItemWriter, ItemStream, InitializingBean, DisposableBean {
public class StaxEventItemWriter implements ItemWriter, ItemStream, InitializingBean {
// default encoding
private static final String DEFAULT_ENCODING = "UTF-8";
@@ -214,14 +213,6 @@ public class StaxEventItemWriter implements ItemWriter, ItemStream, Initializing
Assert.notNull(serializer);
}
/**
* @throws Exception
* @see org.springframework.beans.factory.DisposableBean#destroy()
*/
public void destroy() throws Exception {
close();
}
/**
* Open the output source
*
@@ -264,7 +255,7 @@ public class StaxEventItemWriter implements ItemWriter, ItemStream, Initializing
}
initialized = true;
}
/**
@@ -447,7 +438,8 @@ public class StaxEventItemWriter implements ItemWriter, ItemStream, Initializing
return true;
}
/* (non-Javadoc)
/*
* (non-Javadoc)
* @see org.springframework.batch.item.ItemStream#mark(org.springframework.batch.item.ExecutionAttributes)
*/
public void mark() {
@@ -455,7 +447,8 @@ public class StaxEventItemWriter implements ItemWriter, ItemStream, Initializing
lastCommitPointRecordCount = currentRecordCount;
}
/* (non-Javadoc)
/*
* (non-Javadoc)
* @see org.springframework.batch.item.ItemStream#reset(org.springframework.batch.item.ExecutionAttributes)
*/
public void reset() {