XMLEncoder - Runtime Exception - java

I have been playing around with serialization-XML in java and am a little stuck. When I run this program I get two exceptions and I am not sure what the cause is:
java.lang.InstantiationException: Ship
Continuing ...
java.lang.Exception: XMLEncoder: discarding statement XMLEncoder.writeObject(Ship);
Continuing ...
I suspect that there is something wrong with the class that I am trying to serialize because when I use an example of the internet it works fine.
Can someone please point out what mistake I am making.
Main:
public class Main {
private static final String XMLLocation = "xmlTest.xml";
static ObjectSerializationToXML serializer = new ObjectSerializationToXML();
public Main() {
// TODO Auto-generated constructor stub
}
/**
* #param args
* #throws Exception
*/
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
Ship ship = new Ship("name", "324");
serializer.serializeObjectToXML(XMLLocation, ship);
}
}
Object Serialization-XML Class:
import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class ObjectSerializationToXML {
/**
* <span id="IL_AD10" class="IL_AD">This method</span> saves (serializes) any java bean object into xml file
*/
public void serializeObjectToXML(String xmlFileLocation,
Object objectToSerialize) throws Exception {
FileOutputStream os = new FileOutputStream(xmlFileLocation);
XMLEncoder encoder = new XMLEncoder(os);
encoder.writeObject(objectToSerialize);
encoder.close();
}
/**
* Reads Java Bean Object From XML File
*/
public Object deserializeXMLToObject(String xmlFileLocation)
throws Exception {
FileInputStream os = new FileInputStream(xmlFileLocation);
XMLDecoder decoder = new XMLDecoder(os);
Object deSerializedObject = decoder.readObject();
decoder.close();
return deSerializedObject;
}
}
Object To Serialize (My object that causes the exception):
public class Ship {
private String name;
private String yearBuilt;
public Ship(String name, String yearBuilt) {
this.name = name;
this.yearBuilt = yearBuilt;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getYearBuild() {
return yearBuilt;
}
public void setYearBuild(String yearBuild) {
this.yearBuilt = yearBuild;
}
#Override
public String toString() {
return "ship [name=" + name + ", yearBuilt=" + yearBuilt + "]";
}
}
Object To Serialize (example from the internet that works):
public class MyBeanToSerialize {
private String firstName;
private String lastName;
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}

Whenever any class containing parameterized constructor and trying to serialize, then it should be only instantiated by default Constructor. So, XMLEncoder requires an object to serialize it by default constructor.
Ship class must implement the default constructor while it is containing parameterized constructor because whenever Ship class becomes to serializable, it would be looking for default constructor to instantiate for XMLEncoder.
Please find corrected Ship class as per below.
public class Ship {
private String name;
private String yearBuilt;
public Ship(String name, String yearBuilt) {
this.name = name;
this.yearBuilt = yearBuilt;
}
//Default constructor must be implemented for XMLEncoder serializing
public Ship() {
super();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getYearBuild() {
return yearBuilt;
}
public void setYearBuild(String yearBuild) {
this.yearBuilt = yearBuild;
}
#Override
public String toString() {
return "ship [name=" + name + ", yearBuilt=" + yearBuilt + "]";
}
}

Related

How do I leverage a json mapping file to convert from one pojo to another pojo?

I have two POJOs (Person.java and User.java) that contain similar information. See below:
public class Person {
private String first_name;
private String last_name;
private Integer age;
private Integer weight;
private Integer height;
public String getFirst_name() {
return first_name;
}
public void setFirst_name(String first_name) {
this.first_name = first_name;
}
public String getLast_name() {
return last_name;
}
public void setLast_name(String last_name) {
this.last_name = last_name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Integer getWeight() {
return weight;
}
public void setWeight(Integer weight) {
this.weight = weight;
}
public Integer getHeight() {
return height;
}
public void setHeight(Integer height) {
this.height = height;
}
}
public class User {
private String name_first;
private String name_last;
private Integer my_age;
private Integer my_weight;
private String social_security;
public String getName_first() {
return name_first;
}
public void setName_first(String name_first) {
this.name_first = name_first;
}
public String getName_last() {
return name_last;
}
public void setName_last(String name_last) {
this.name_last = name_last;
}
public Integer getMy_age() {
return my_age;
}
public void setMy_age(Integer my_age) {
this.my_age = my_age;
}
public Integer getMy_weight() {
return my_weight;
}
public void setMy_weight(Integer my_weight) {
this.my_weight = my_weight;
}
public String getSocial_security() {
return social_security;
}
public void setSocial_security(String social_security) {
this.social_security = social_security;
}
}
I have defined a mapping.json file as shown below using GSON.
{
"columnMap": [
{
"userColumn": "name_first",
"personColumn": "first_name"
},
{
"userColumn": "last_first",
"personColumn": "first_last"
},
{
"userColumn": "my_age",
"personColumn": "age"
},
{
"userColumn": "my_weight",
"personColumn": "weight"
}
]
}
public class Mapping {
private ArrayList<Pair> columnMap;
public Mapping(){
columnMap = new ArrayList<>();
}
public ArrayList<Pair> getColumnMap() {
return columnMap;
}
public void setColumnMap(ArrayList<Pair> columnMap) {
this.columnMap = columnMap;
}
}
I am writing a utility class helper function that converts between a Person and User object the mapped pairs.
public class Pair {
private String userColumn;
private String personColumn;
public String getUserColumn() {
return userColumn;
}
public void setUserColumn(String userColumn) {
this.userColumn = userColumn;
}
public String getPersonColumn() {
return personColumn;
}
public void setPersonColumn(String personColumn) {
this.personColumn = personColumn;
}
public static void main(String args[]){
}
}
My question is below:
As you can see the returnVal object is being set by me (the programmer) to convert from a User POJO to a Person POJO. How do I leverage the pre-defined mapping.json to do this? The reason I am asking is in the future, the mapping.json file may change (maybe the weight mapping no longer exists). So I am trying to avoid re-programming this Utility.userToPerson() function. How can I achieve this? I am thinking Java reflection is the way to go, but I would like to hear back from the Java community.
public class Utility {
public static Person userToPerson(User u){
Person returnVal = new Person();
returnVal.setAge(u.getMy_age()); // <-- Question How do I leverage mapping.json here?
returnVal.setFirst_name(u.getName_first());
returnVal.setLast_name(u.getName_last());
returnVal.setWeight(u.getMy_weight());
return returnVal;
}
}
You can introspect the beans (i.e. User and Person) for the field names and call corresponding getter from User to fetch the value. Later call corresponding setter in Person.
Here I have taken userToPersonFieldsMap for mapping the field, you can load mapping from JSON file and construct the map accordingly.
Important code section is the for loop, where it dynamically calls getter and setter and does the job.
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
public class UserToPersonMapper {
public static void main(String[] args) throws IntrospectionException, InvocationTargetException, IllegalAccessException {
Map<String, String> userToPersonFieldsMap = new HashMap<>();
userToPersonFieldsMap.put("name_first", "first_name");
userToPersonFieldsMap.put("last_first", "first_last");
userToPersonFieldsMap.put("age", "personAge");
//existing user
User user = new User("Tony", "Stark", 20);
//new person - to be initialised with values from user
Person person = new Person();
for (Map.Entry<String, String> entry : userToPersonFieldsMap.entrySet()) {
Object userVal = new PropertyDescriptor(entry.getKey(), User.class).getReadMethod().invoke(user);
new PropertyDescriptor(entry.getValue(), Person.class).getWriteMethod().invoke(person, userVal);
}
System.out.println(user);
System.out.println(person);
}
}
class User {
private String name_first;
private String last_first;
private int age;
public User(String name_first, String last_first, int age) {
this.name_first = name_first;
this.last_first = last_first;
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName_first() {
return name_first;
}
public String getLast_first() {
return last_first;
}
public void setName_first(String name_first) {
this.name_first = name_first;
}
public void setLast_first(String last_first) {
this.last_first = last_first;
}
#Override
public String toString() {
return "User{" +
"name_first='" + name_first + '\'' +
", last_first='" + last_first + '\'' +
", age=" + age +
'}';
}
}
class Person {
private String first_name;
private String first_last;
private int personAge;
public void setFirst_name(String first_name) {
this.first_name = first_name;
}
public void setFirst_last(String first_last) {
this.first_last = first_last;
}
public String getFirst_name() {
return first_name;
}
public String getFirst_last() {
return first_last;
}
public int getPersonAge() {
return personAge;
}
public void setPersonAge(int personAge) {
this.personAge = personAge;
}
#Override
public String toString() {
return "Person{" +
"first_name='" + first_name + '\'' +
", first_last='" + first_last + '\'' +
", personAge=" + personAge +
'}';
}
}
You can tweak and try it out this example to make it more align with your requirement.
Note:
This solution uses reflection.

How to set private variable in java bean

I have a java bean class such as :
public class EncBean {
private String name;
private String ReversedBinary;
private String ConcatenatedData;
public String getReversedBinary() {
return ReversedBinary;
}
public void setReversedBinary(String ReversedBinary) {
this.ReversedBinary = ReversedBinary;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getConcatenatedData() {
return ConcatenatedData;
}
public void setConcatenatedData(String name) {
this.ConcatenatedData = ConcatenatedData;
}
}
and I tried to set a value for the private java bean field(ConcatenatedData) as follow :
public EncBean conctdat(){
EncBean encBean4 = new EncBean();
encBean4.setConcatenatedData(inputkey.concat(var));
return encBean4;
}
and in main i tried to access this value as:
mainenc concatdata =new mainenc();
EncBean encbeandata = concatdata.conctdat();
System.out.println("concatenated data is: "+encbeandata.getConcatenatedData());
but it gives me null
concatenated data is: null
You should fix implementation of setConcatenatedData() to :
public void setConcatenatedData(String name) {
this.ConcatenatedData = name; // instead of this.ConcatenatedData = ConcatenatedData
}
The first one is:
public void setConcatenatedData(String name) {
this.ConcatenatedData = name;
}
Second one, you should double check if inputkey.concat(var) is null.
You can do it by Getter & Setter.
This will help:
setConcatenatedData(String name) {
this.ConcatenatedData = name;
}

Import csv's into data stax cassandra through spark (Java Api)

Is there a way to import csv into cassandra through spark's java api without creating a pojo class for the csv. I am able to insert the csv by creating a pojo class like below , Is there any way to do so without creating pojo class for the csv programatically using spark java api.
My csv looks like this
Name,Age,bg,sex
ammar,67,ab+,M
nehan,88,b+,M
moin,99,m+,M
arbaaz,67,a+,M
...
And the program is below.
import org.apache.commons.lang3.StringUtils;
import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.Function;
import com.cassandra.insertion.MergeGeneSymDataInsertion;
import com.cassandra.insertion.MergeGeneSymDataInsertion.HgIpsenGeneSym;
import com.publicdata.task.PublicDataInsertion.PublicData;
import static com.datastax.spark.connector.japi.CassandraJavaUtil.*;
public class InsertCsv {
static JavaSparkContext ctx = null;
static boolean isHeader = true;
public static void main(String[] args) {
try {
ctx = new JavaSparkContext(new SparkConf().setMaster("local[4]")
.setAppName("TestCsvInserion"));
insertCsv(ctx);
} catch (Exception e) {
e.printStackTrace();
}
}
private static void insertCsv(JavaSparkContext ctx) {
JavaRDD<String> testfileRdd = ctx
.textFile("/home/syedammar/Pilot Project /test.csv");
JavaRDD<Bats> batsclassRdd = testfileRdd
.map(new Function<String, Bats>() {
#Override
public Bats call(String line) throws Exception {
// TODO Auto-generated method stub
if(!isHeader){
String[] words=StringUtils.split(line, ",");
String name = words[0];
String age = words[1];
String bg = words[2];
String sex = words[3];
return new Bats(name, age, bg, sex);
}
else
{
isHeader=false;
return null;
}
}
}).filter(new Function<Bats, Boolean>() {
#Override
public Boolean call(Bats obj) throws Exception {
// TODO Auto-generated method stub
return obj!=null;
}
}).coalesce(1);
javaFunctions(batsclassRdd).writerBuilder("test", "bats", mapToRow(Bats.class)).saveToCassandra();
}
public static class Bats {
public Bats() {
// TODO Auto-generated constructor stub
}
private String name;
private String age;
private String bg;
public Bats(String name, String age, String bg, String sex) {
super();
this.name = name;
this.age = age;
this.bg = bg;
this.sex = sex;
}
private String sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getBg() {
return bg;
}
public void setBg(String bg) {
this.bg = bg;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
}
Yes you can do that. I found it while browsing... please refer -
How to Parsing CSV or JSON File with Apache Spark
There are two approaches, follow Procedure for approach B
POJO classes are not required for the approach B, but POJO classes would make your code easier to read if you are using Java
Hope this will help.

Convert Object to String

I have a couple to class in which I'm getting and setting a few things and then finally calling it in my main method. But when I call my class in the main method it just gives me the object instead of name,address and age. I know this structure is very complicated but I want to keep this structure because later on I will be adding a lot of things to this. It would be AMAZING if someone could tell me how to do this. I would really appreciate this. Below is my code for all my classes
This is my first class
public class methodOne
{
public String getName()
{
String name = "UserOne";
return name;
}
public int getAge()
{
int age = 17;
return age;
}
public String getAddress()
{
String address = "United States";
return address;
}
}
This is my second class
public class methodTwo
{
String name;
String address;
int age;
public methodTwo(methodOne objectOne)
{
name=objectOne.getName();
address=objectOne.getAddress();
age=objectOne.getAge();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
This is my third class
public class methodThree {
private methodTwo methodTwoInMethodThree;
private methodOne methodOneInMethodThree;
public methodThree()
{
this.methodOneInMethodThree = new methodOne();
this.methodTwoInMethodThree = new methodTwo(methodOneInMethodThree);
}
public methodTwo getMethodTwoInMethodThree() {
return methodTwoInMethodThree;
}
public void setMethodTwoInMethodThree(methodTwo methodTwoInMethodThree) {
this.methodTwoInMethodThree = methodTwoInMethodThree;
}
}
This is my fourth class which is the method maker
public class methodMaker {
public methodThree brandNewFunction(methodTwo object)
{
methodThree thirdMethod = new methodThree();
thirdMethod.setMethodTwoInMethodThree(object);
return thirdMethod;
}
}
This is my main class which calls methodMaker. What I want to achieve is that when I print the value it should print the name,address and age but instead it just prints trial.methodThree#4de5ed7b
public class mainClass {
public static void main(String args[])
{
methodMaker makerOfMethods = new methodMaker();
methodOne one = new methodOne();
methodTwo object = new methodTwo(one);
System.out.println(makerOfMethods.brandNewFunction(object).toString());
}
}
What you need to do is to override the default implementation of the .toString() method in the objects you want to print out:
#Override
public String toString()
{
return "Name: " + this.name;
}
EDIT:
I do not know exactly where you are printing, and you naming convention doesn't really help out, but from what I am understanding, you would need to implement it in all of you classes since they all seem to be related to each other.
So, in your methodOne class (can also be applied to methodTwo):
#Override
public String toString()
{
return "Name: " + this.name + " Age: " + this.age + " Address: + " this.address;
}
In your methodThree class:
private methodTwo methodTwoInMethodThree;
private methodOne methodOneInMethodThree;
#Override
public String toString()
{
StringBulder sb = new StringBuilder();
if(this.methodTwoInMethodThree != null)
{
sb.append("Method 2:").append(methodTwoInMethodThree.toString());
}
if(methodOneInMethodThree != null)
{
sb.append("Method 1:").append(methodOneInMethodThree.toString());
}
return sb.toString();
}
When you call
MyClass myObject = new MyClass();
System.out.println(myObject);
Implicitly , java calls instead
System.out.println(myObject.toString());
So, if in MyClass, you override toString(), then whatever your toString method returns is what's gonna be printed.
Side note: are you confusing classes and methods? Methods are functions in your classes, classes are wrappers around a bunch of attributes and methods. Your naming is confusing.
try this code:
public class methodTwo
{
String name;
String address;
int age;
public methodTwo(methodOne objectOne)
{
name=objectOne.getName();
address=objectOne.getAddress();
age=objectOne.getAge();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String toString(){
return name+" "+address+" "+age;
}
}
Are you printing the object using println()?
From the docs, println():
calls at first String.valueOf(x) to get the printed object's string value
This string value is obtained from the object's toString() method, which:
returns a string consisting of the name of the class of which the object is an instance, the at-sign character `#', and the unsigned hexadecimal representation of the hash code of the object
So if you want to print anything other than this you have to override the toString() method in your object and return a string containing whatever you want.
Just google "override tostring java" and you will see a ton of examples.

Output showing null values. how to resolve

i have three classes :
CustomerData.java
import java.util.Date;
public class CustomerData
{
private String FirstName;
private String LastName;
private int TaxId;
private String HomePhone;
private String WorkPhone;
private String HomeAddress;
private Date Dob;
private String EmployerName;
private boolean isEmployed;
private String ProDescription;
private String IsSameAsPrevious;
public String getFirstName() {
return FirstName;
}
public void setFirstName(String firstName) {
FirstName = firstName;
}
public String getLastName() {
return LastName;
}
public void setLastName(String lastName) {
LastName = lastName;
}
public int getTaxId() {
return TaxId;
}
public void setTaxId(int taxId) {
TaxId = taxId;
}
public String getHomePhone() {
return HomePhone;
}
public void setHomePhone(String homePhone) {
HomePhone = homePhone;
}
public String getWorkPhone() {
return WorkPhone;
}
public void setWorkPhone(String workPhone) {
WorkPhone = workPhone;
}
public String getHomeAddress() {
return HomeAddress;
}
public void setHomeAddress(String homeAddress) {
HomeAddress = homeAddress;
}
public Date getDob() {
return Dob;
}
public void setDob(Date dob) {
Dob = dob;
}
public String getEmployerName() {
return EmployerName;
}
public void setEmployerName(String employerName) {
EmployerName = employerName;
}
public boolean isEmployed() {
return isEmployed;
}
public void setEmployed(boolean isEmployed) {
this.isEmployed = isEmployed;
}
public String getProDescription() {
return ProDescription;
}
public void setProDescription(String proDescription) {
ProDescription = proDescription;
}
public String getIsSameAsPrevious() {
return IsSameAsPrevious;
}
public void setIsSameAsPrevious(String isSameAsPrevious) {
IsSameAsPrevious = isSameAsPrevious;
}
}
MainCntrlr.java
public class MainCntrlr {
public static void main(String[] args)
{
CustomerData customerData=new CustomerData();
customerData.setFirstName("RAVI");
customerData.setLastName("Shekhar");
customerData.setHomePhone("123456789");
customerData.setWorkPhone("1256554634");
customerData.setHomeAddress("Banagalore");
customerData.setEmployerName("ABc");
customerData.setProDescription("New Produtc");
customerData.setTaxId(1233434343);
ContrOne ctr=new ContrOne();
ctr.displayInformation();
}
}
ContrOne.java
import com.blr.CustomerData;
public class ContrOne
{
public void displayInformation()
{
CustomerData cd=new CustomerData();
System.out.println("displaying customer Info");
System.out.println(cd.getFirstName());
System.out.println(cd.getLastName());
System.out.println(cd.getHomePhone());
System.out.println(cd.getWorkPhone());
System.out.println(cd.getEmployerName());
System.out.println(cd.getProDescription());
System.out.println(cd.getDob());
System.out.println(cd.getTaxId());
}
}
Output is :
displaying customer Info
null
null
null
null
null
null
null
0
In your method ContrOne.displayInformation() you create a new new CustomerData() object. Thus it is not properly initialized. Maybe you want to pass customerData from your main method to displayInformation?
You are creating a CustomerData object in MainCntrlr class but not passing it to the ContrOne class. ContrOne is creating it's own CustomerData object and printing it's values which are null.
A possible solution could be to change the signature of displayInfo and pass the CustomerData object to this method from MainCntrlr class.
A few other points to note
The class names are confusing. It is not clear why you have created MainCntrlr and ContrOne classes separately.
If all you want is to display Customer information, you may want to override the toString() method in CustomerData class instead.
Your ContrOne.displayInformation() instantiates a new CustomerData() object to cd but never populates fields in it.
If you want your ContrOne to display information, rather do this:
public class ContrOne {
public void displayInformation(CustomerData cd) {
System.out.println("displaying customer Info");
System.out.println(cd.getFirstName());
System.out.println(cd.getLastName());
System.out.println(cd.getHomePhone());
System.out.println(cd.getWorkPhone());
System.out.println(cd.getEmployerName());
System.out.println(cd.getProDescription());
System.out.println(cd.getDob());
System.out.println(cd.getTaxId());
}
}
and in MainCntrlr
public static void main(String[] args) {
CustomerData customerData=new CustomerData();
customerData.setFirstName("RAVI");
customerData.setLastName("Shekhar");
customerData.setHomePhone("123456789");
customerData.setWorkPhone("1256554634");
customerData.setHomeAddress("Banagalore");
customerData.setEmployerName("ABc");
customerData.setProDescription("New Produtc");
customerData.setTaxId(1233434343);
ContrOne ctr=new ContrOne();
ctr.displayInformation(customerData);
}

Categories