Q:

How to run read() function only once Spring Batch

I am creating a Spring Batch job with folowing xml:   
<batch:job id="simulatorJob" restartable="false">
    <batch:step id="step1">
        <batch:tasklet transaction-manager="transactionManager">
            <batch:chunk reader="stockListner" writer="customWriter"
                commit-interval="5">
            </batch:chunk>
        </batch:tasklet>
    </batch:step>
</batch:job>

<bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />

<bean id="stockListner" class="com.XXX.stock.java.StockReader" scope="step">
    <property name="URL" value="NTPC,TCS" />
    <!-- <property name="URL" value="NTPC" /> -->
    <!-- <property name="URL" value="TCS" /> -->
</bean>

<bean id="customWriter" class="com.XXX.stock.java.FlatFileWriter" />

This is my reader class:  
private String URL;

public String getURL() {
    return URL;
}

public void setURL(String uRL) {
    URL = uRL;
}

public ArrayList<StockData> read() throws Exception, UnexpectedInputException,ParseException, NonTransientResourceException {
    ArrayList<StockData> list = new ArrayList<StockData>();
    String[] splitStocks = URL.split(",");      

    for(int i=0; i < splitStocks.length;i++){
        list.add(stockReader.getStockData(splitStocks[i]));     
    }
    return list;        
}  

But the reader class keeps on running. How do I stop at first run?   
I tried this aswell:   
public StockData read() throws Exception, UnexpectedInputException,ParseException, NonTransientResourceException {
    ArrayList<StockData> list = new ArrayList<StockData>();
    String[] splitStocks = URL.split(",");

    for(int i=0; i < splitStocks.length;i++)
    {  
           return stockReader.getStockData(splitStocks[i]);
    }

    return null;
}  

The read() function goes into loop..

A:

Quoting ItemReader.read() Javadoc:

Reads a piece of input data and advance to the next one. Implementations must return null at the end of the input data set.

As such, you need to return null after the first read to indicate to Spring Batch that there is nothing more to read.

A:

This simple delegate encapsulate one-time reading.
class OneItemReader<T> implements ItemReader<T> {
  boolean read = false;
  ItemReader<T> delegate;

  @Override
  public T read() {
    if(read) {
      return null;
    }
    T item = delegate.read();
    read = true;
    return item;
  }
}

You can create you own reader without think about one-time reading and wrap it using this small delegate.
Your StockURLReader may be defined as
class StockURLReader implements ItemReader<StockReader> {
  String[] tokens = new String[0];
  int index = 0;
  StockDAO stockReader;

  void setURL(String URL) {
    this.tokens = URL.split(",");
    index = 0;
  }

  StockData read() {
    if(index < tokens.length) {
      return stockReader.getStockData(tokens[index++]);
    }
    return null;
  }
}

Create OneTimeReader and set StockURLReader as delegate and you have separate StockData reading from one-time reading logic.
If you want to read a group of StockData the best solution is to create a StockDataListBean where you store all StockData read from a splitted URL.
class StockDataListBean {
  List<StockData> data = new LinkedList<StockData>();
}

and modify StockURLReader as:
class StockURLReader implements ItemReader<StockDataListBean> {
  String[] URLs = new String[0];
  int index;
  StockDAO stockReader;

  void setURLs(String[] URL) {
    this.URLs = URL;
    index = 0;
  }

  StockDataListBean read() {
    StockDataListBean item = null;
    if(index < URLs.length)
    {
      item = new StockDataListBean();
      for(String token : URLs[index].split(",").length)
      {
        item.data.add(stockReader.getStockData(token));
      }
    }
    return item;
  }
}

