java - FlatFileItemReader cannot be cast when being accessed from custom ItemReader -
i have application i'm attempting diagnose in setup i've done incorrectly, , not having luck in determining why it's not working outside of specific situations.
first code i'm using.
configuration.java
@enablebatchprocessing @springbootapplication(scanbasepackages="com.lcbo") @enableintegration public class config { @autowired private jobbuilderfactory jobbuilderfactory; @autowired private stepbuilderfactory stepbuilderfactory; @autowired private lcboinventorytrackerproperties inventorytrackerproperties; @bean public job processlcboinventory(@qualifier("getlcbostoredatastep") final step getlcbostoredatastep) { return jobbuilderfactory .get("processlcboinventory") .incrementer(new runidincrementer()) .start(getlcbostoredatastep) .build(); } /** * tasklet downloads .zip file, unzips, , saves in appropriate folder under resources. * execute @ 6am daily * // * @param acquiredatafiletasklet acquiredatafiles * @return step - returns step status; either success or failure */ @bean public step getcurrentlcbodatastep(final acquiredatafiletasklet acquiredatafiles, final executioncontextpromotionlistener listener) { return stepbuilderfactory .get("getcurrentlcbodatastep") .tasklet(acquiredatafiles) .allowstartifcomplete(true) .listener(listener) .build(); } @bean public step getlcbostoredatastep(final lcbostorereader lcbostorereader, final lcbostorewriter lcbostorewriter) { return stepbuilderfactory .get("getlcbostoredatastep") .<lcbostore, lcbostore>chunk(inventorytrackerproperties.getdefaults().getchunksize()) .reader(lcbostorereader) .writer(lcbostorewriter) .build(); } }
the reader class
@component public class lcbostorereader extends abstractlcboreader implements itemreader, interstepdataretriever { private static final logger log = loggerfactory.getlogger(lcbostorereader.class); @override public itemreader<lcbostore> read() throws unexpectedinputexception, parseexception, nontransientresourceexception { class<lcbostore> classtype = lcbostore.class; return createcsvreader(classtype, currentcsvfilepath, inventorytrackerproperties.getlcbofilpropertiess().getstores()); } /* @override public void beforestep(final stepexecution stepexecution) { jobexecution jobexecution = stepexecution.getjobexecution(); executioncontext jobcontext = jobexecution.getexecutioncontext(); this.currentworkingdate = (string) jobcontext.get("currentworkingdatekey"); } */ @override public void retrieveinterstepdatafromjobcontext(final executioncontext jobcontext) { this.currentcsvfilepath = (string) jobcontext.get("currentcsvfilepathkey"); } }
and class extends (because flatfileitemreader setup used multiple readers)
public abstract class abstractlcboreader { @autowired protected lcboinventorytrackerproperties inventorytrackerproperties; protected string currentcsvfilepathkey; protected string currentcsvfilepath; private static final logger log = loggerfactory.getlogger(abstractlcboreader.class); protected <t> itemreader<t> createcsvreader(final class<t> classtype, final string currentcsvfilepath, final lcbofiledetailsproperties properties) { flatfileitemreader<t> reader = new flatfileitemreader<>(); // skip line ignore header information in these files reader.setlinestoskip(properties.getnumberoflinestoskipinfile()); reader.setresource(new filesystemresource(currentcsvfilepath + file.separator + properties.getfilename())); reader.setlinemapper(createlinemapper(classtype, properties)); reader.setrecordseparatorpolicy(new defaultrecordseparatorpolicy()); reader.setencoding("utf8"); return reader; } private <t> linemapper<t> createlinemapper(final class<t> classtype, final lcbofileproperties.lcbofiledetailsproperties properties) { defaultlinemapper<t> linemapper = new defaultlinemapper<>(); linemapper.setlinetokenizer(createlinetokenizer(properties)); linemapper.setfieldsetmapper(createfieldsetmapper(classtype)); return linemapper; } private <t> fieldsetmapper<t> createfieldsetmapper(final class<t> classtype) { beanwrapperfieldsetmapper<t> fieldsetmapper = new beanwrapperfieldsetmapper<>(); fieldsetmapper.settargettype(classtype); return fieldsetmapper; } private linetokenizer createlinetokenizer(final lcbofileproperties.lcbofiledetailsproperties properties) { lcbofileproperties.column[] columns = properties.getcolumns(); int[] columnindexes = new int[columns.length]; string[] columnnames = new string[columns.length]; // populating columnindexes (int = 0; < columns.length; i++) { columnindexes[i] = columns[i].getcolumnindex(); columnnames[i] = columns[i].getcolumnname(); } delimitedlinetokenizer linetokenizer = new delimitedlinetokenizer(); linetokenizer.setincludedfields(columnindexes); linetokenizer.setnames(columnnames); linetokenizer.setdelimiter(","); linetokenizer.setquotecharacter('"'); return linetokenizer; } }
the error when executing object cannot cast flatfileitemreader object passed first parameter in createcsvreader. here's example.
public class lcbostore { private long id; private string addresslineone; private string addresslinetwo; private string city; private string postalcode; private string latitude; private string longitude; private string updatedat; //convert date public lcbostore(final long id, final string addresslineone, final string addresslinetwo, final string city, final string postalcode, final string latitude, final string longitude, final string updatedat) { this.id = id; this.addresslineone = addresslineone; this.addresslinetwo = addresslinetwo; this.city = city; this.postalcode = postalcode; this.latitude = latitude; this.longitude = longitude; this.updatedat = updatedat; } public long getid() { return id; } public string getaddresslineone() { return addresslineone; } public string getaddresslinetwo() { return addresslinetwo; } public string getcity() { return city; } public string getpostalcode() { return postalcode; } public string getlatitude() { return latitude; } public string getlongitude() { return longitude; } public string getupdatedat() { return updatedat; } public void setid(final long id) { this.id = id; } public void setaddresslineone(final string addresslineone) { this.addresslineone = addresslineone; } public void setaddresslinetwo(final string addresslinetwo) { this.addresslinetwo = addresslinetwo; } public void setcity(final string city) { this.city = city; } public void setpostalcode(final string postalcode) { this.postalcode = postalcode; } public void setlatitude(final string latitude) { this.latitude = latitude; } public void setlongitude(final string longitude) { this.longitude = longitude; } public void setupdatedat(final string updatedat) { this.updatedat = updatedat; } @override public string tostring() { return "storedbmodel [id=" + id + ", addresslineone=" + addresslineone + ", city=" + city + ", postalcode=" + postalcode + ", latitude=" + latitude + ", longitude=" + longitude + ", updatedat=" + updatedat + "]"; } }
now if move flatfileitemreader mode exists in createcsvreader constructor of custom reader class, or have it's in configuration file, works fine. however, couldn't figure out how work job , step context in configurations (the constructor executes before can access step , jobcontext seems testing, , never figure how access when put in config class.). plus me @ least, looks cleaner have reader code in it's own file not being stuffed in constructor.
so in nutshell, there way fix os having in it's own reader class work? doing incorrectly , using bad practices? maybe mix of two? if there's missing please ask away , i'll attempt clarify.
so found answer simple in comments. here's solution.
first, add bolded code abstract class createcsvwriter method
**protected <t> t** createcsvreader(final class<t> classtype, final string currentcsvfilepath, final lcbofiledetailsproperties properties) throws exception { flatfileitemreader<t> reader = new flatfileitemreader<>(); // skip line ignore header information in these files reader.setlinestoskip(properties.getnumberoflinestoskipinfile()); reader.setresource(new filesystemresource(currentcsvfilepath + file.separator + properties.getfilename())); reader.setlinemapper(createlinemapper(classtype, properties)); reader.setrecordseparatorpolicy(new defaultrecordseparatorpolicy()); reader.setencoding("utf8"); **return reader.read();** }
doing read call manually prevent returning more needed reader class. in reader class edit following
@override public **lcbostore** read() throws **exception**, unexpectedinputexception, parseexception, nontransientresourceexception { class<lcbostore> classtype = lcbostore.class; return createcsvreader(classtype, currentcsvfilepath, inventorytrackerproperties.getlcbofilpropertiess().getstores()); }
this returns object you've created , hence issue resolved.
Comments
Post a Comment