0

I am using JavaPoet api for generating the source code. However, at some point I am fetching the require details from xml that is ready made string for creating fields then I save the string to Object and then I cast object to FieldSpec but it is giving me Exception. Is that I am casting it in wrong way?

public List<FieldSpec> getFieldSpec() throws JDOMException{
    try {
        fieldSpec = new ArrayList<FieldSpec>();//com.squareup.javapoet.FieldSpec
        SAXBuilder builder = new SAXBuilder();
        xmlFile = new File("CodeGenerationXML\\SourceCodeFieldsXML\\Fields.xml");
        doc = builder.build(xmlFile);
        RootXMLFields = doc.getRootElement();
        for(Element field:RootXMLFields.getChild("Fields").getChildren()){
            Object ElementField = field.getText();// returns FieldSpec.builder(String.class,"str").initializer("$S","Hello").addModifiers(Modifier.PRIVATE, Modifier.FINAL).build()
            fieldSpec.add((FieldSpec) ElementField);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return fieldSpec;
}
public static void main(String arg[]) throws JDOMException{
    new AddUpdateFieldsXML().getFieldSpec();
}

Exception:

Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to com.squareup.javapoet.FieldSpec
at RandD.AddUpdateFieldsXML.getFieldSpec(AddUpdateFieldsXML.java:94)
at RandD.AddUpdateFieldsXML.main(AddUpdateFieldsXML.java:103)
Learner
  • 15
  • 1
  • 7
  • Check the return type of `Element.getText()`, seems like it's not returning what you think it is, but rather a `String`. – Magnus Apr 01 '16 at 08:54
  • @BadCash, yes it is a string which I am getting from xml – Learner Apr 01 '16 at 09:11
  • There is no reason to declare the variable `ElementField` to have the type `Object` when `field.getText()` actually returns a `String`. If you declared the variable `ElementField` straight-forward as `String`, the compiler already told you at compile-time that the cast to `FieldSpec` is invalid. – Holger Apr 01 '16 at 09:16
  • Well there's your problem... You can't just cast a `String` to a `FieldSpec` and expect it to work. You have to somehow get that `String` into a `FieldSpec` object, probably by using `FieldSpec.builder()` (I'm not familiar with JavaPoet). – Magnus Apr 01 '16 at 09:17
  • @BadCash, Yes you are right – Learner Apr 01 '16 at 09:21
  • Did you try something along the lines of `fieldSpec.add( FieldSpec.builder(String.class, field.getText()).initializer("$S","Hello").addModifiers(Modifier.PRIVATE, Modifier.FINAL).build() );`? – Magnus Apr 01 '16 at 09:34
  • Yes, initially I have created class with required Fields `FieldSpec.builder(WebDriver.class,elementName).addModifiers(Modifier.PRIVATE).build();` but to make process fast and easy I have created the xml, so as soon as required field is passed in method in background I create xml with `FieldSpec.builder(WebDriver.class,elementName).addModifiers(Modifier.PRIVATE).build();` so that while create source I just read the xml and add the FieldSpec value from xml that is `FieldSpec fieldSpec = value as string gets from xml, which is then I add in list and pass it to create field method – Learner Apr 01 '16 at 09:56
  • `TypeSpec helloWorld = TypeSpec.classBuilder(className) .addModifiers(Modifier.PUBLIC, Modifier.FINAL) .addFields(fields)/* fields is List fields = new ArrayList();*/ .addMethods(methods) .build();` – Learner Apr 01 '16 at 09:57

3 Answers3

0

Use the builder method like the example in the comment to create the FieldSpec object from the text in the XML element before adding it to the list.

stepanian
  • 11,373
  • 8
  • 43
  • 63
  • I try with `fieldSpec.add((FieldSpec.Builder) ElementField);` but no luck.. Is this you are trying to explain? – Learner Apr 01 '16 at 09:12
0

You can't just cast some object to a FieldSpec object. When you are using the JavaPoet API, you have to use FieldSpec.builder for every field you want to create. That's how the API works. See this API.

Arka Ghosh
  • 845
  • 1
  • 11
  • 23
  • do you mean `fieldSpec.add((FieldSpec.Builder) ElementField);` this? – Learner Apr 01 '16 at 09:22
  • Nope. `FieldSpec.Builder.build()` will give you a `FieldSpec` object. I have provided you the API link. You could have gone through that. – Arka Ghosh Apr 01 '16 at 10:25
  • Thanks for your reply, I have already used `FieldSpec.builder(String.class,"str").initializer("$S","value").addModifiers(Modifier.PRIVATE, Modifier.FINAL).build()` which is working fine but now I am reading this from xml file which will return me read made format string that is "FieldSpec.builder(String.class,elementName).initializer("$S",elementValue).addModifiers(Modifier.PRIVATE, Modifier.FINAL).build()" and now I want to add whole this string to List as FieldSpec object – Learner Apr 01 '16 at 10:47
0

As per your Exception log

Exception in thread "main" java.lang.ClassCastException: java.lang.String 
cannot be cast to com.squareup.javapoet.FieldSpec

this means there is no IS-A relationship of Class com.squareup.javapoet.FieldSpec to class java.lang.String. So, String value will not be assigned or cast to any non- varient type.

Here This code generate Exception

  Object ElementField = field.getText();// return String Values and Store it into the Object. 
  FieldSpec.builder(String.class,"str").initializer("$S","Hello").addModifiers(Modifier.PRIVATE, Modifier.FINAL).build()
            fieldSpec.add((FieldSpec) ElementField); // ElementField contains String Object.

Here, field.getText(); getText() Method will return String Value and Store it into the Object which is OK because Object Class is parent of All Other Classes exists in Java .

Now, (FieldSpec) ElementField You are tring to cast String to a class FieldSpec which is not relevant to the java. Because There is no Relationship between FieldSpec and String Class.

So, (FieldSpec) ElementField this peice of code will raise the exception.

Vikrant Kashyap
  • 6,398
  • 3
  • 32
  • 52