Buggy code:
public abstract class AbstractRecordReader < T extends PrepareConfiguration > implements RecordReader < T > { private static final Logger LOG = Logger . getLogger ( AbstractRecordReader . class . getName ( ) ) ; protected T conf ; protected RecordWriter writer ; protected Record writtenRecord ; protected Source source ; protected String [ ] actualColumnNames ; protected String [ ] columnNames ; protected ColumnType [ ] columnTypes ; protected Set < String > skipColumns = new HashSet < String > ( ) ; protected String primaryKey ; protected ColumnType primaryKeyType ; protected TimeColumnValue timeColumnValue ; protected long lineNum = 0 ; private Writer errWriter ; private boolean errWriterCreated = false ; protected AbstractRecordReader ( T conf , RecordWriter writer ) { } public void configure ( Task task ) throws PreparePartsException { } public void resetLineNum ( ) { } public void incrementLineNum ( ) { } public long getLineNum ( ) { } public String [ ] getActualColumnNames ( ) { } public String [ ] getColumnNames ( ) { } public ColumnType [ ] getColumnTypes ( ) { } public Set < String > getSkipColumns ( ) { } public void setSkipColumns ( ) { } public int getTimeColumnIndex ( ) { } public int getAliasTimeColumnIndex ( int timeColumnIndex ) { } public void validateTimeAndPrimaryColumn ( int timeColumnIndex , int aliasTimeColumnIndex ) throws PreparePartsException { } public void initializeColumnTypes ( TimeColumnSampling [ ] sampleColumnValues ) { } public TimeColumnValue getTimeColumnValue ( ) { } public void setTimeColumnValue ( TimeColumnSampling [ ] sampleColumnValues , int timeColumnIndex , int aliasTimeColumnIndex ) { } private TimeColumnValue createTimeColumnValue ( int index , boolean isAlias , Strftime strftime ) { } public void initializeWrittenRecord ( ) { } public boolean next ( ) throws PreparePartsException { } public abstract boolean readRecord ( ) throws PreparePartsException , IOException { } public abstract void convertTypes ( ) throws PreparePartsException { } public abstract String getCurrentRecord ( ) { } public void handleError ( PreparePartsException e ) throws PreparePartsException { } public void close ( ) throws IOException { } public void writeErrorRecord ( String record ) { } public void createErrWriter ( ) { String errDirName = conf . getErrorRecordsOutputDirName ( ) ; String srcName = source . getPath ( ) ; <START_BUG> int lastSepIndex = srcName . lastIndexOf ( File . separatorChar ) ; <END_BUG> String prefix = srcName . substring ( ( lastSepIndex + 1 ) , srcName . length ( ) ) . replace ( '.' , '_' ) ; String errFileName = prefix + ".error-records.txt" ; File dir = new File ( errDirName ) ; if ( dir . exists ( ) ) { dir . mkdirs ( ) ; } File errFile = new File ( errDirName , errFileName ) ; if ( errFile . exists ( ) ) { errFile . delete ( ) ; } try { errWriterCreated = errFile . createNewFile ( ) ; AbstractRecordReader . LOG . info ( String . format ( "error<seq2seq4repair_space>records<seq2seq4repair_space>file<seq2seq4repair_space>is<seq2seq4repair_space>created:<seq2seq4repair_space>%s" , errFile . getAbsolutePath ( ) ) ) ; } catch ( IOException e ) { AbstractRecordReader . LOG . log ( Level . WARNING , "error<seq2seq4repair_space>records<seq2seq4repair_space>file<seq2seq4repair_space>cannot<seq2seq4repair_space>be<seq2seq4repair_space>created" , e ) ; } try { errWriter = new BufferedWriter ( new OutputStreamWriter ( new FileOutputStream ( errFile ) ) ) ; } catch ( FileNotFoundException e ) { AbstractRecordReader . LOG . log ( Level . WARNING , "error<seq2seq4repair_space>records<seq2seq4repair_space>writer<seq2seq4repair_space>cannot<seq2seq4repair_space>be<seq2seq4repair_space>created" , e ) ; } } public void closeErrWriter ( ) { } }

Fix:
int lastSepIndex = srcName . lastIndexOf ( source . getSeparatorChar ( ) ) ;