I am making an Email Client(for class) and i want to store the messages i send everyday in a single file.I am going to use serialization for this.I tried appending to a file by setting append to true in FileOutputStream.Below is the code i wrote.But it throws a StreamCorruptedException(stack trace given below).I cannot seem to find the reason why.I would like to know whether there is a better way to store multiple objects to a single file using serialization.Any help is appreciated.Thanks in advance.
//For reading and writing objects to files
interface MyFileHandler<T> {
public void write(T input );
public ArrayList<T> read();
}
class FileHandlerObject implements MyFileHandler<EmailMessage>
{
public void write(EmailMessage input){
try{
FileOutputStream fileOutputStream = new FileOutputStream("emails.ser",true);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(input);
objectOutputStream.flush();
objectOutputStream.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
public ArrayList<EmailMessage> read(){
ArrayList<EmailMessage> messages=new ArrayList<EmailMessage>();
try{
FileInputStream fileInputStream=new FileInputStream("emails.ser");
ObjectInputStream objectInputStream=new ObjectInputStream(fileInputStream);
boolean cont = true;
while (cont) {
if(fileInputStream.available()!=0)
{
Object obj=objectInputStream.readObject();
EmailMessage message=(EmailMessage)obj;
messages.add(message);
}
else{
cont=false;
}
}
objectInputStream.close();
return messages;
}
catch(IOException e)
{
e.printStackTrace();
}
catch(ClassNotFoundException c)
{
c.printStackTrace();
}
catch(ClassCastException c)
{
c.printStackTrace();
}
return null;
}
public static void main(String[] args) {
FileHandlerObject f=new FileHandlerObject();
ArrayList<EmailMessage> a=f.read();
a=f.read();
}
}
And the Email Message class that i serialize
public class EmailMessage implements Serializable{//implement serializables
private String recipient;
private String subject;
private String content;
private String date;
public void setRecipient(String recipient)
{
this.recipient=recipient;
}
public String getRecipient()
{
return this.recipient;
}
public void setSubject(String subject){
this.subject=subject;
}
public void setContent(String content){
this.content=content;
}
public String getSubject(){
return this.subject;
}
public String getContent(){
return this.content;
}
public void setDate(String date)
{
this.date=date;
}
public String getDate()
{
return this.date;
}
public String printDetails()
{
String details="Recipient: "+getRecipient()+
"\nSubject: "+getSubject()+
"\nEmail content: "+getContent()+
"\nDate Sent: "+getDate();
return details;
}}
And below is the stack trace
java.io.StreamCorruptedException: invalid type code: AC
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1723)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:508)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:466)
at FileHandlerObject.read(MyFileHandler.java:46)
at FileHandlerObject.main(MyFileHandler.java:89)
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 months ago.
Improve this question
How can i fix problem with load ArrayList from file?
Full code is on the git:
project github link
When I load data from file I'll get it back -> IOException
I'm learning to use the stream so I'm writing it to a file.
After the end of the program, I want to write the time the user has reached in the arraylist and list all the times with which the game was finished.
package sk.games.puzzle;
import java.io.*;
import java.util.*;
public class BestTimes implements Iterable<BestTimes.PlayerTime>, Serializable{
private static final String BESTTIME_DB = System.getProperty("user.home")
+ System.getProperty("file.separator")
+ "best.time";
private List<PlayerTime> playerTimes = new ArrayList<>();
public Iterator<PlayerTime> iterator() {
return playerTimes.iterator();
}
public void addTime(String name, int time){
playerTimes.add(new PlayerTime(name, time));
Collections.sort(playerTimes);
}
public void load(){
ObjectInputStream load = null;
try {
load = new ObjectInputStream(new FileInputStream(BESTTIME_DB));
playerTimes = (ArrayList<PlayerTime>) load.readObject();
} catch (FileNotFoundException e) {
System.err.println("fail nebola najdena db");
} catch (IOException e) {
System.err.println("fail nebola otvorena db");
} catch (ClassNotFoundException e) {
System.err.println("fail nebol najdeny zaznam");
} finally {
if (load != null) {
try {
load.close();
} catch (IOException e) {
//empty
}
}
}
}
public void save() {
ObjectOutputStream save = null;
try {
save = new ObjectOutputStream(new FileOutputStream(BESTTIME_DB));
save.writeObject(playerTimes);
} catch (FileNotFoundException e) {
System.err.println("fail db neexistuje");
} catch (IOException e) {
System.err.println("fail nepodarilo sa otvorit db");
} finally {
if (save != null) {
try {
save.close();
} catch (IOException e) {
//empty
}
}
}
}
#Override
public String toString() {
Formatter f = new Formatter();
for (int i = 0; i < playerTimes.size(); i++) {
PlayerTime pt = playerTimes.get(i);
f.format("%02d. %s - %ds.\n", i, pt.getName(), pt.getTime());
}
return f.toString();
}
public static class PlayerTime implements Comparable<PlayerTime> {
private final String name;
private final int time;
public PlayerTime(String name, int time) {
this.name = name;
this.time = time;
}
public String getName() {
return name;
}
public int getTime() {
return time;
}
#Override
public int compareTo(PlayerTime o){
return Integer.compare(this.time, o.getTime());
}
}
}
The problem is that your PlayerTime class is not serializable.
public static class PlayerTime implements Comparable<PlayerTime> { }
should be
public static class PlayerTime implements Comparable<PlayerTime> implements Serializable { }
It's not necessary to make BestTimes serializable unless you do write BestTimes object to file.
I have been struggling to create a serializing method that serializes all my already existing objects. This is what I have done:
my class:
public class Test implements Serializable{
ArrayList<TheOtherClass> obj = new ArrayList<>();
public static void main(String[] args) {
Test test = new Test();
test.addTest("This", "Is", "Some");
test.addTest("Text", "As", "Example");
test.saveAllArrays();
}
// omitted code down here.
public void addTest(String some, String random, String text) {
obj.add(new TheOtherClass(some, random, text));
}
public void saveTest(Object obj) throws IOException{
ObjectOutputStream save = new ObjectOutputStream(new FileOutputStream("SaveFile.bin"));
save.writeObject(obj);
}
public void saveAllArrays(){
for(TheOtherClass all : obj){
try {
saveTest(all);
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
}
my object class:
public class TheOtherClass implements Serializable{
private String some;
private String random;
private String savedText;
Getter and setter methods are omitted.
Here is a complete example. Hopefully it will get you moving.
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class Test implements Serializable {
private static final String FILE = "SaveFile.bin";
private List<Item> itemList = new ArrayList<>();
public class Item implements Serializable {
private String first;
private String second;
private String last;
public Item(String first, String second, String last) {
this.first = first;
this.second = second;
this.last = last;
}
#Override
public String toString() {
return first + ", " + second + ", " + last;
}
}
public static void main(String args[]) {
Test test = new Test();
if(args.length > 0) {
try {
test.loadItemList();
System.out.println("loaded");
test.printList();
} catch (IOException | ClassNotFoundException e) {
System.out.println(e.getMessage());
}
} else {
test.addItem("1", "2", "done");
test.addItem("Text", "As", "Example");
try {
test.saveItemList();
System.out.println("saved");
test.printList();
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
private void printList() {
itemList.forEach(System.out::println);
}
private void addItem(String first, String second, String last) {
itemList.add(new Item(first, second, last));
}
private void loadItemList() throws IOException, ClassNotFoundException {
InputStream inputStream = new FileInputStream(FILE);
ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
itemList = (List<Item>) objectInputStream.readObject();
}
private void saveItemList() throws IOException {
OutputStream outputStream = new FileOutputStream(FILE);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
objectOutputStream.writeObject(itemList);
}
}
At present you're creating a new file per serialized object, so you lose all but the last one. There is no need to serialize multiple objects at all, or iterate over the array list. Just save it directly, and deserialize it directly too.
This question already has answers here:
java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException
(2 answers)
Closed 6 years ago.
I am trying to read all objects from the file. Below is the snippet of the method use to fetch list of object from file.
public List displayParties() {
ObjectInputStream ois = null;
List<RegisterParty> results = new ArrayList();
try {
FileInputStream fis = new FileInputStream("/media/user/disk2/myapp/assignment/party.ser");
ois = new ObjectInputStream(fis);
while (true) {
System.out.println(" inside while true");
results.add((RegisterParty) ois.readObject());
System.out.println(results);
}
} catch (IOException ex) {
ex.printStackTrace();
}
catch (Exception ex){
ex.printStackTrace();
} finally{
try {
ois.close();
}catch (IOException ex){
ex.printStackTrace();
}
}
return results;
}
RegisterParty Class :
public class RegisterParty implements Serializable {
String bookingPersonName;
String childName;
String childAge;
String theme;
String foodAlergies;
String noOfGuest;
String specialGuest;
public String getBookingPersonName() {
return bookingPersonName;
}
public void setBookingPersonName(String bookingPersonName) {
this.bookingPersonName = bookingPersonName;
}
public String getChildName() {
return childName;
}
public void setChildName(String childName) {
this.childName = childName;
}
public String getChildAge() {
return childAge;
}
public void setChildAge(String childAge) {
this.childAge = childAge;
}
public String getTheme() {
return theme;
}
public void setTheme(String theme) {
this.theme = theme;
}
public String getFoodAlergies() {
return foodAlergies;
}
public void setFoodAlergies(String foodAlergies) {
this.foodAlergies = foodAlergies;
}
public String getNoOfGuest() {
return noOfGuest;
}
public void setNoOfGuest(String noOfGuest) {
this.noOfGuest = noOfGuest;
}
public String getSpecialGuest() {
return specialGuest;
}
public void setSpecialGuest(String specialGuest) {
this.specialGuest = specialGuest;
}
public String toString(){
return bookingPersonName+" "+childName+" "
+childAge+" "+foodAlergies+" "+theme+" "+noOfGuest+" "+specialGuest;
}
}
But getting the below exception :
java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: models.RegisterParty
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1354)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)
at helper.HelperFunctions.displayParties(HelperFunctions.java:39)
at services.PartyOperations.listAllParties(PartyOperations.java:64)
at assignment.App.main(App.java:34)
at helper.HelperFunctions.saveParty(HelperFunctions.java:24)
at services.PartyOperations.registerParty(PartyOperations.java:53)
at assignment.App.main(App.java:28)
Caused by: java.io.NotSerializableException: models.RegisterParty
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1183)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347)
at helper.HelperFunctions.saveParty(HelperFunctions.java:20)
at services.PartyOperations.registerParty(PartyOperations.java:52)
... 1 more
RegisterParty implements the serializable interface. Its a menu based app, so when i save the object in file, its save successfully. But call the method to get all object in list, its throw the exception. Any Idea why?
This method successfully execute to serialize the object:
public void saveParty(RegisterParty registerParty){
try {
FileOutputStream fout = new FileOutputStream("/media/user/disk2/myapp/assignment/party.txt");
ObjectOutputStream oos = new ObjectOutputStream(fout);
oos.writeObject(registerParty);
oos.close();
System.out.println("Successfull Register");
System.out.println("========Select you choice========");
App.main(str);
}
catch (Exception ex){
ex.printStackTrace();
}
}
When I implement a Serializable object I add a static variable serialVersionUID to the class:
private static final long serialVersionUID = -1892561327013038124L;
This line gets added as a suggestion by either the eclipse or android studio. I don't know how to do it with IntelliJIdea.
It worth a try! I believe this ID used for deserialisation.
There was conflict in fileToRead & fileToWrite.
FileInputStream fis = new FileInputStream("/media/user/disk2/myapp/assignment/party.ser");
FileOutputStream fout = new FileOutputStream("/media/user/disk2/myapp/assignment/party.txt");
I have two classes , utilisateur ( means user in french ) and Envellope ( wich means envelope ), so i have many classes to organize sending and receiving objects to/from two classes in localhost !
I want to print the result in the screen after sending and receiving.
I conclude that it's not deserializing and the output of toString is a kind of hashcode like this #14ae5a5
Envellope class:
public class Envellope<T> implements Serializable{
private static final long serialVersionUID = -5653473013975445298L;
public String todo;
public T thing;
public Envellope() {
}
public Envellope(String todo, T thing) {
this.todo = todo;
this.thing = thing;
}
}
Utilisateur class:
public class utilisateur implements Serializable{
private static final long serialVersionUID = -5429001491604482315L;
public String login;
public String mdp;
public utilisateur(String l,String m){
login=l;
mdp=m;
}
public utilisateur(){}
}
and there is the main (Client):
public static void main(String[] args) {
try {
Socket socket=new Socket("localhost",4444);
StreamObject so=new StreamObject(socket);
Envellope<utilisateur> toSend=new Envellope<utilisateur>("Authenticate",new utilisateur("addou","ismail"));
so.send(toSend);//sending to ServerSocket
Envellope<utilisateur> env=(Envellope<utilisateur>) so.receive();//receiving from server
System.out.println(env.todo+" Object: "+env.thing);
} catch (IOException ex) {
Logger.getLogger(Aaa.class.getName()).log(Level.SEVERE, null, ex);
}
}
I didn't write here the other classes, because i think it works , but if you need it just tell me !
StreamObject class:
public class StreamObject extends IOS{
private ObjectOutputStream oos;
private ObjectInputStream ois;
public StreamObject(Socket s) throws IOException{
super();
super.os=s.getOutputStream();
super.is=s.getInputStream();
oos=new ObjectOutputStream(os);
ois=new ObjectInputStream(is);
}
And IOS class is just inputStream and OutputStream !
public void send(Object object) {
try {
oos.writeObject(object);
} catch (IOException e) {
System.out.print("Erreur receive socket: ");
System.err.print("IOException ");
System.out.println(e.getMessage());
}
}
public Object receive() {
try {
return ois.readObject();
} catch (ClassNotFoundException e) {
System.out.print("Erreur receive socket: ");
System.err.print("ClassNotFoundException ");
System.out.println(e.getMessage());
} catch (IOException e) {
System.out.print("Erreur receive socket: ");
System.err.print("IOException ");
System.out.println(e.getMessage());
}
return null;
}
}
Your utilisateur class does not override toString, so it uses the default implementation, which returns the class name and hash code.
Add something like this to utilisateur:
#Override
public String toString() {
return "login="+login+" & mdp="+mdp;
}
I am writing some code to parse java source code. I am experimenting with Eclipse JDT AST Parser. My code is given below. (Parsing code). I am testing the parser against a Mailer application that I wrote in Java (second code snippet). My parser is visiting all methods except the generateEmail() and the debug() methods. I have looked all over the place but I am not able to understand for the life of me why its happening. Can anyone tell me what I am doing wrong? Is it a memory issue? I am not getting any OutOfMemoryException
I want to visit the specific methods with the MethodVisitor method to get access to statements and variables in a particular method.
My Parsing code
public class RuleEngine {
public static void parse(String file) {
File java = new File(file);
ASTParser parser = ASTParser.newParser(AST.JLS3);
String code = readFile(java);
parser.setSource(code.toCharArray());
parser.setKind(ASTParser.K_COMPILATION_UNIT);
final CompilationUnit cu = (CompilationUnit) parser.createAST(null);
cu.accept(new ASTVisitor() {
public boolean visit(ImportDeclaration id) {
Name imp = id.getName();
debug("import", id.getName().getFullyQualifiedName());
return false;
}
public boolean visit(VariableDeclarationFragment node) {
SimpleName name = node.getName();
debug("var.declaration", (name.getFullyQualifiedName() + ":" + cu.getLineNumber(name.getStartPosition())));
return false; // do not continue
}
public boolean visit(MethodDeclaration method) {
debug("method", method.getName().getFullyQualifiedName());
debug("method.return", method.getReturnType2().toString());
List<SingleVariableDeclaration> params = method.parameters();
for(SingleVariableDeclaration param: params) {
debug("param", param.getName().getFullyQualifiedName());
}
Block methodBlock = method.getBody();
String myblock = methodBlock.toString();
methodVisitor(myblock);
return false;
}
});
}
public static void methodVisitor(String content) {
debug("entering met visitor", "1");
ASTParser metparse = ASTParser.newParser(AST.JLS3);
metparse.setSource(content.toCharArray());
metparse.setKind(ASTParser.K_STATEMENTS);
Block block = (Block) metparse.createAST(null);
block.accept(new ASTVisitor() {
public boolean visit(VariableDeclarationFragment var) {
debug("met.var", var.getName().getFullyQualifiedName());
return false;
}
public boolean visit(SimpleName node) {
debug("SimpleName node", node.getFullyQualifiedName());
return false;
}
public boolean visit(IfStatement myif) {
debug("if.statement", myif.toString());
return false;
}
});
}
public static void debug(String ref, String message) {
System.out.println(ref +": " + message);
}
public static void main(String[]args) {
parse("MailerDaemon.java");
}
This is my MailerDaemon Code
public boolean isBccMode() {
return bccMode;
}
public void setBccMode(boolean bccMode) {
this.bccMode = bccMode;
}
public void setServerPort(String serverPortAddr) {
String[] elems = serverPortAddr.split("\\:");
this.setServerAddr(elems[0]);
this.setSmtpPort(elems[1]);
}
public String getServerAddr() {
int i = 0;
return serverAddr;
}
public void setServerAddr(String serverAddr) {
this.serverAddr = serverAddr;
}
public boolean isSslOn() {
return isSslOn;
}
public void setSslOn(boolean isSslOn) {
this.isSslOn = isSslOn;
}
public String getSmtpPort() {
return smtpPort;
}
public void setSmtpPort(String smtpPort) {
this.smtpPort = smtpPort;
}
public String getFromEmail() {
return fromEmail;
}
public void setFromEmail(String fromEmail) {
this.fromEmail = fromEmail;
}
public String getToEmails() {
return toEmails;
}
public void setToEmails(String toEmails) {
this.toEmails = toEmails;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getCcList() {
return ccList;
}
public void setCcList(String ccList) {
this.ccList = ccList;
}
public String getBccList() {
return bccList;
}
public void setBccList(String bccList) {
this.bccList = bccList;
}
public String getFile() {
return file;
}
public void setFile(String file) {
debug("filename: " + file);
this.file = file;
}
public void generateEmail() {
Properties props = new Properties();
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.port", this.getSmtpPort());
if(isSslOn()) {
props.put("mail.smtp.socketFactory.port", this.getSmtpPort());
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
}
props.put("mail.smtp.host", getServerAddr());
Session session = Session.getDefaultInstance(props, new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(getUsername(), getPassword());
}
});
Message msg = new MimeMessage(session);
try {
msg.setFrom(new InternetAddress(this.getFromEmail()));
if (getToEmails() != null) {
msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(getToEmails()));
} else if (isBccMode()) {
msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(getFromEmail()));
}
//msg.setRecipients(Message.RecipientType.CC, InternetAddress.parse(getCcList()));
msg.setSubject(getSubject());
//msg.setText(getMessage());
MimeBodyPart messagePart = new MimeBodyPart();
messagePart.setText(getMessage());
/*
MimeBodyPart attachments = new MimeBodyPart();
FileDataSource fd = new FileDataSource(getFile());
attachments.setDataHandler(new DataHandler(fd));
attachments.setFileName(fd.getName());
*/
Multipart mp = new MimeMultipart();
mp.addBodyPart(messagePart);
//mp.addBodyPart(attachments);
msg.setContent(mp);
Transport.send(msg);
debug("Done. Closing Session...");
} catch (AddressException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (MessagingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static void debug(String message) {
System.out.println("[DEBUG]: " + message);
}
I see no evident problem with your parsing code. I hope its failing somewhere when its trying to parse the generateEmail() method. Since the parser follows a sequential approach, the debug() method is also not getting parsed. Try to enclose the statements within the public boolean visit(MethodDeclaration method) in a try-catch block with probably a Throwable clause.
Also have a check for your readFile() method. One issue that is mostly seen while reading a file is missing to append new line character to each line. Not appending a new line results in erroneous construction of the code, especially when there are comments in the code. You may inspect compilationUnit.getProblems() method to check any such problems.
#UnniKris - Thank you for your response. I changed the readFile() method and included a \n after the newline was written to the StringBuilder. This worked. All my methods were successfully parsed.
My code snippet for the readFile() method is posted here:
public static String readFile(File file) {
StringBuilder sb = new StringBuilder();
try {
Scanner scan = new Scanner(file);
while(scan.hasNext()) {
sb.append(scan.nextLine()+"\n"); //added the new line feed here
}
scan.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String fullcode = sb.toString();
//debug("full.code", fullcode);
return fullcode;
}