0

I am reading a CSV file with BeanIO. The objects represented in the CSV are Field objects, and when I read the file, they come back as such, and I can see them in the debug utilities that everything is ok. However, when I try to parse the objects to their type in order to access the properties on them, I get a class cast exception as follows:

java.lang.ClassCastException: util.flatfile.model.classes.Field cannot be cast to util.flatfile.model.classes.Field
    at util.csvreader.util.CSVBeanReader.read(CSVBeanReader.gs:19)
    at program_.__Program__1983.evaluate(Unknown Source)
    at gw.internal.gosu.parser.GosuProgram.runProgram(GosuProgram.java:420)
    at gw.internal.gosu.parser.GosuProgram.evaluate(GosuProgram.java:253)
    at gw.internal.gosu.parser.GosuProgram_Proxy.evaluate(gw.internal.gosu.parser.GosuProgram_Proxy:2)
    at gw.internal.gosu.parser.ExecutionEnvironment$1.evaluate(ExecutionEnvironment.java:542)
    at gw.internal.gosu.parser.ExecutionEnvironment$1.runScript(ExecutionEnvironment.java:522)
    at gw.internal.gosu.parser.ExecutionEnvironment$1.run(ExecutionEnvironment.java:488)
    at java.lang.Thread.run(Thread.java:724)

My read method is as follows

class CSVBeanReader implements BeanReader {
  override function read(): Object {
    // create a StreamFactory
    var factory = StreamFactory.newInstance()
    // load the mapping file
    factory.load("C:\\Dev\\modules\\configuration\\gsrc\\util\\csvreader\\util\\fieldMapping.xml")

    // use a StreamFactory to create a BeanReader
    using (var beanReader = factory.createReader("fields", new File("C:\\Dev\\modules\\configuration\\gsrc\\util\\csvreader\\util\\vendorDef.csv"))) {
      try {
        var field = beanReader.read()
        while (field != null) {
          print((field as Field)) //EXCEPTION OCCURS HERE

          // process the record...
          field = beanReader.read()
        }
      } catch (var e: InvalidRecordException) {
        var context = e.getRecordContext()
        if (context.hasRecordErrors()) {
          for (error in context.getRecordErrors()) {
            print("Error: ${error}")
            // handle record errors...
          }
        }
        if (context.hasFieldErrors()) {
          for (field in context.getFieldErrors().keySet()) {
            for (error in context.getFieldErrors(field)) {
              print("Error: ${error}")
              // handle field error...
            }
          }
        }
      }
    }
    return null
  }
}

My Field Class:

class Field {
  private var _startPos: int as StartPosition
  private var _length: int as Length
  private var _fieldName: String as Name
  private var _param1: String as Parameter1
  private var _format: String as Format
  private var _justify: String as Justify
  private var _fill: String as Fill
  private var _truncate: String as Truncate
  private var _stripType: String as StripType
  private var _strip: String as Strip
  private var _data: String as Data
  private var _param2: String as Parameter2
  construct() {
  }

  construct(startPos: int, fieldLength: int, fieldName: String,
            param1: String, format: String, justify: String, fill: String, truncate: String,
            stripType: String, strip: String, data: String, param2: String) {
    _startPos = startPos
    _length = fieldLength
    _fieldName = fieldName
    _param1 = param1
    _format = format
    _justify = justify
    _fill = fill
    _truncate = truncate
    _stripType = stripType
    _data = data
    _param2 = param2
  }
}

My CSV input:

Field,File Header,1,1,Constant,'',None,Left,' ',Right,'None','','1',''
Field,File Header,2,2,Constant,'',None,Left,'0',Right,'None','','',''
Field,File Header,4,10,Destination DDA,'',None,Right,'0',Left,'None','','',''
Field,File Header,14,10,Constant,'',None,Left,' ',Right,'None','','0111000025',''
Field,File Header,24,6,File Creation Date,'',YYMMDD,Right,'0',Left,'None','','',''
Field,File Header,30,4,File Creation Date,'',HHMM,Right,'0',Left,'None','','',''
Field,File Header,34,47,Constant,'',None,Left,' ',Right,'None','','',''

and my mapping xml:

<beanio xmlns="http://www.beanio.org/2012/03"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.beanio.org/2012/03 http://www.beanio.org/2012/03/mapping.xsd">

    <stream name="fields" format="csv">
        <record name="field" class="util.flatfile.model.classes.Field">
            <field name="entryType" rid="true" literal="Field" ignore="true" />
            <field name="recordType" ignore="true" />
            <field name="startPosition" type="int" />
            <field name="length" type="int"/>
            <field name="name" />
            <field name="parameter1" />
            <field name="format" />
            <field name="justify" />
            <field name="fill" />
            <field name="truncate" />
            <field name="stripType" />
            <field name="strip" />
            <field name="data" />
            <field name="parameter2" />
        </record>
    </stream>

</beanio>

I've read that it's likely caused by classloaders, but I don't see why it would be an issue here. Any ideas?

Thanks

smur89
  • 329
  • 1
  • 3
  • 15
  • Did you add a serial ID to your bean ? http://stackoverflow.com/questions/285793/what-is-a-serialversionuid-and-why-should-i-use-it – BatScream Sep 15 '14 at 14:04
  • The error shows that two different class loaders each have a Field class. Not used BeanIO myself, but in general start removing copies of jars with the Field class. Should be loaded at one spot. – Joop Eggen Sep 15 '14 at 14:09
  • @BatScream I added the serial ID and implemented Serializable but it had no effect. – smur89 Sep 15 '14 at 14:33
  • @JoopEggen I change the class name from Field to make sure this wasn't the issue. and the problem persists. java.lang.ClassCastException: tdic.util.flatfile.model.classes.FlatFileField cannot be cast to tdic.util.flatfile.model.classes.FlatFileField... There's no other jars being used here. – smur89 Sep 15 '14 at 14:34
  • It seems that BeanIO loads the class from the specification in XML and you are loading the class by a regular import. You can load the returned field in an Object, and dump its class loader, the same for `Field.class.getClassLoader()`. I bet the class loaders are different. One from gosu. Try **interfaces**, maybe that is portable. – Joop Eggen Sep 15 '14 at 14:55
  • @JoopEggen hm, they both come back as sun.misc.Launcher$AppClassLoader@5c335297! – smur89 Sep 15 '14 at 15:12
  • 1
    Then use `print((Field) field);` - gosu might be misleading us, so let's do a java cast. – Joop Eggen Sep 15 '14 at 15:26
  • @JoopEggen Java cast also produces the ClassCastException! I am thinking I'll just use Apache POI-XSSF and do it myself, it's a simple task that I'm trying to accomplish really! – smur89 Sep 15 '14 at 15:40
  • 1
    **Makes solid sense.** Also noone answered and you probably sought sample code already. – Joop Eggen Sep 15 '14 at 15:49
  • @JoopEggen Thanks for the help, appreciate it. – smur89 Sep 15 '14 at 15:50

0 Answers0