I'm making a java program as a challenge to myself to learn, and I'm currently having trouble with serializing and de-serializing an arraylist. When I de-serialize all of the values are null.
This is the function that initially serializes the list:
private void saveModList(ArrayList<Moderator> m) {
try {
ObjectOutputStream fOut = new ObjectOutputStream(new FileOutputStream("data/modlist.ctm"));
fOut.writeObject(m);
fOut.close();
} catch(IOException ex) {
JOptionPane.showMessageDialog(null, "Could not save moderator list.",
"Save error", JOptionPane.ERROR_MESSAGE);
ex.printStackTrace();
}
}
This is the function that deserializes the list:
public static ArrayList<Moderator> openModList() {
try {
ObjectInputStream fIn = new ObjectInputStream(new FileInputStream("data/modlist.ctm"));
try {
return (ArrayList<Moderator>) fIn.readObject();
} catch (ClassNotFoundException ex) {
JOptionPane.showMessageDialog(null, "Could not open moderator list",
"Read error", JOptionPane.ERROR_MESSAGE);
ex.printStackTrace();
}
fIn.close();
} catch(FileNotFoundException ex) {
JOptionPane.showMessageDialog(null, "Could not load moderator data. File not found.",
"Moderator file not found.", JOptionPane.ERROR_MESSAGE);
ex.printStackTrace();
} catch(EOFException ex) {
} catch(IOException ex) {
JOptionPane.showMessageDialog(null, "Could not load moderator data.",
"Error", JOptionPane.ERROR_MESSAGE);
ex.printStackTrace();
}
//If something screws up, return null, and the user will not be logged in
return null;
}
And this calls the function to deserialize
ArrayList<Moderator> modLoginList = new ArrayList<Moderator>();
modLoginList = Main.openModList();
//Check all of the moderators.
//If one of them matches up to a moderator username and password, log them in
for(int i = 0; i < modLoginList.size(); i++) {
if(modLoginList.get(i).name.equals(username) && modLoginList.get(i).password.equals(password)) {
loggedIn = true;
break;
}
}
When I do this, I also get a NullPointerException at the if statement, checking if the moderator's credentials are valid. When I go and just try and print out the values outright, they are null. The moderator class does implement serializable and has a serial version ID. Any suggestions on why this is happening and how to fix it/better ways to do this are greatly appreciated.
Also it is not just returning null outright because there was nothing to read, or something went wrong.
The NullPointerException appears to come from the openModList method returning null. One option is to surround your for loop with a null check:
if (modLoginList != null) {
for(int i = 0; i < modLoginList.size(); i++) {
if(modLoginList.get(i).name.equals(username) && modLoginList.get(i).password.equals(password)) {
loggedIn = true;
break;
}
}
}
It's possible that the object reference you're serializing is null. So check the part of your code that adds objects to the ArrayList before passing it for serialization.
That said, your code could use other changes, such as instead of this block:
try {
return (ArrayList<Moderator>) fIn.readObject();
} catch (ClassNotFoundException ex) {
...
ex.printStackTrace();
}
fIn.close();
add a finally clause:
try {
return (ArrayList<Moderator>) fIn.readObject();
} catch (ClassNotFoundException ex) {
...
ex.printStackTrace();
} finally {
fIn.close();
}
The finally clause will be executed regardless of what happens with the try/catch clauses.
Related
-The array of appliances(clock,lamp or television) is displayed on an array of labels (pictures[]) in a 3x3 grid
-An example of outputting an appliance icon (which is when a device is added to the grid though a button labelled 'add device')
Television myTelevision = new Television();
appliance[count-1] = myTelevision;
pictures[count-1].setIcon(appliance[count-1].getPicture());
This is my code for saving the array of appliances (objects) to a file and reading them back in ( re-populating the appliance array):
if(e.getSource()==but3)
{
ObjectInputStream input
= null;
try {
input = new ObjectInputStream(
new FileInputStream("livingroom.bat"));
Appliance[] appliance = (Appliance[]) (input.readObject());
} catch (IOException ex) {
Logger.getLogger(HomeController.class.getName()).log(Level.SEVERE, null, ex);
} catch (ClassNotFoundException ex)
{
Logger.getLogger(HomeController.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
input.close();
} catch (IOException ex) {
Logger.getLogger(HomeController.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
if(e.getSource()==but4)
{
ObjectOutputStream output
= null;
try {
output = new ObjectOutputStream(
new FileOutputStream("livingroom.bat", true));
output.writeObject(appliance);
} catch (IOException ex) {
Logger.getLogger(HomeController.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
output.close();
} catch (IOException ex) {
Logger.getLogger(HomeController.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
After deserialization I am trying to display the imageicon for the appliances in the array (which has just been re-populated). However no matter how I try nothing seems to happen (the grid of pictures shows no change).
What I am asking for: Can anyone tell me a method of applying the image icons for the appliances to the grid of pictures once deserialization has taken place?
You are deserialising into a local variable whose scope ends with the try block it is declared in, and you don't do anything with the local variable, so nothing happens.
Presumably you should be deserialing into a member variable.
EDIT: The error was caused by Netbeans not the code. Post has been edited to show all the code since the Git files are being removed.
I have a group project at school to design a tower defense game and I have been attempting to add Serialization.
Here is the code:
public class Serialization implements Serializable {
private static FileOutputStream file;
private static ObjectOutputStream write;
public static boolean checkFile(String name){
boolean check = false;
check = new File("log",name+".ser").isFile();
return check;
}
public static void createFile(String name) {
try {
file = new FileOutputStream("log/"+name+".ser");
} catch (FileNotFoundException ex) {
Logger.getLogger(Serialization.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static ObjectOutputStream openFile(String name) {
try {
file = new FileOutputStream("log/"+name+".ser");
write = new ObjectOutputStream(file);
} catch (FileNotFoundException ex) {
Logger.getLogger(Serialization.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(Serialization.class.getName()).log(Level.SEVERE, null, ex);
}
return write;
}
public static void addLine(ObjectOutputStream con,Object data) {
try {
con.writeObject(data);
} catch (IOException ex) {
Logger.getLogger(Serialization.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static void readLine(String name){
FileInputStream fileIn = null;
try {
fileIn = new FileInputStream("log/"+name+".ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
System.out.println(in.readObject());
in.close();
fileIn.close();
} catch (FileNotFoundException ex) {
Logger.getLogger(Serialization.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(Serialization.class.getName()).log(Level.SEVERE, null, ex);
} catch (ClassNotFoundException ex) {
Logger.getLogger(Serialization.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
fileIn.close();
} catch (IOException ex) {
Logger.getLogger(Serialization.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public static void closeFile(ObjectOutputStream con){
try {
con.close();
} catch (IOException ex) {
Logger.getLogger(Serialization.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
I eventually abandoned it for two reasons. One it was overkill (trying to have a central class that handles multiple serialization files) and two I could not get it to work with what I am about to talk about.
What I really wanted was to serialize the enemyArray. This holds every living enemy in the game and all their information (stats). If you scroll down to line 192 that is what is left of my serialization attempts:
public void serialize(){
if (Serialization.checkFile("test")==false){
Serialization.createFile("test");
}
ObjectOutputStream connection = Serialization.openFile("test");
for (int x=0;x<enemyArray.length;x++){
if (enemyArray[x]!=null){
Serialization.addLine(connection,enemyArray[x]);
}
}
//Serialization.addLine(connection,enemyArray);
Serialization.closeFile(connection);
enemyArray = null;
Serialization.readLine("test");
//System.out.println(enemyArray[0].id);
// try {
// FileOutputStream fileOut = new FileOutputStream("log/test.ser");
// ObjectOutputStream out = new ObjectOutputStream(fileOut);
// out.writeObject(enemyArray);
// out.writeUTF(t);
// // Do work here
// for (int x=0;x<enemyArray.length;x++){
// if (enemyArray[x]!=null){
// Enemy tmp = enemyArray[x];
// System.out.println(tmp+" >>> "+enemyArray[x]);
// out.writeObject(tmp);
// }
// }
// out.close();
// fileOut.close();
// } catch (FileNotFoundException ex) {
// Logger.getLogger(EnemyController.class.getName()).log(Level.SEVERE, null, ex);
// } catch (IOException ex) {
// Logger.getLogger(EnemyController.class.getName()).log(Level.SEVERE, null, ex);
// }
}
}
It will create the file but will not save anything to it. What is wrong with the code? from what I studied enemyArray shouldn't be static so I removed that and still no change.
Try doing a out.flush(); brefore you close thre output stream.
I found the error after some troubleshooting in the computer lab with my group. Hopefully this can help anyone who finds themselves in my situation or in a similar Java file read/ write issue.
My IDE, Netbeans, shows the file in the files and project list once it is dynamically created, but because it was filled with serialized data and was created after the project was opened and run it would only display an empty file when in reality there is actually data inside the file. String data is fine so it may only be certain data types (like serialized objects) that trigger this error.
Several different versions of my code were correct but they all seemed broken because an empty file was returned to the IDE. The solution is two fold:
Manually check it through your file explorer. It will show a size and can be opened in another editor but may still be buggy in the IDE you ran the program in.
Close down your IDE and on reopening, at least in Netbeans case, the file should be updated correctly.
On a similar note Netbeans may just all together keep showing the empty file instead of offering you the option to select the files encoding. Just view the file in your explorer in this case and if the size is greater than 0 you know your code is ok. This is purely an IDE error.
I have a program that needs to load data at launch. The data comes from a serialized object. I have a method loadData(), which is called upon construction of the Data class. Sometimes, (I.e. after a loss of saveData, or on first program launch on a new system), the file can be empty. (The file will exist though, the method ensures that).
When I try to run the program, I recieve an EOFException. So, in the method, I try to catch it, and just print a line to the console explaining what happened and return to the caller of the method. (so, upon return, the program will think loadData() is complete and has returned. However, it still crashes throwing the exception without printing a line to the console or anything. It is like it is totally ignoring the catch I have in place.
CODE:
protected void loadData()
{
// Gets/creates file object.
saveFileObject = new File("savedata.ser");
if(!saveFileObject.exists())
{
try
{
saveFileObject.createNewFile();
}
catch(IOException e)
{
System.out.println("Uh oh...");
e.printStackTrace();
}
}
// Create file input stream
try
{
fileIn = new FileInputStream(saveFileObject);
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
// Create object input stream
try
{
inputStream = new ObjectInputStream(fileIn);
}
catch(IOException e)
{
e.printStackTrace();
}
// Try to deserialize
try
{
parts = (ArrayList<Part>)inputStream.readObject();
}
catch(EOFException e)
{
System.out.println("EOFException thrown! Attempting to recover!");
return;
}
catch(ClassNotFoundException e)
{
e.printStackTrace();
}
catch(IOException e)
{
e.printStackTrace();
}
// close input stream
try
{
inputStream.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
Any help please?
Try writing your code like :
protected void loadData() {
// Gets/creates file object.
saveFileObject = new File("savedata.ser");
try {
if (!saveFileObject.exists()) {
saveFileObject.createNewFile();
}
// Create file input stream
fileIn = new FileInputStream(saveFileObject);
// Create object input stream
inputStream = new ObjectInputStream(fileIn);
// Try to deserialize
parts = (ArrayList<Part>) inputStream.readObject();
// close input stream
inputStream.close();
} catch (EOFException e) {
System.out.println("EOFException thrown! Attempting to recover!");
} catch (IOException e) {
System.out.println("Uh oh...");
e.printStackTrace();
}
}
Also note that EOFException is a sub-class of IOException
How about making one try and then making catches respectively like here?
I'm a beginner still, and currently learning about handling exceptions. The exercise in my book I'm trying to figure out tells me to add a Finally block to close out the file I opened, and I don't understand what I'm doing wrong. Keep in mind the file name and path are fake but here is what I have:
public static String readLineWithFinally()
{
System.out.println("Starting readLineWithFinally method.");
RandomAccessFile in = new RandomAccessFile("products.ran", "r");
try
{
String s = in.readLine();
return s;
}
catch (IOException e)
{
System.out.println(e.toString());
return null;
}
finally
{
try
{
in.close();
}
catch (Exception e)
{
System.out.println("Generic Error Message");
}
}
}
To add on to Taylor Hx's answer, you can take advantage of Java 7's try-with-resources construct to avoid having to use finally altogether in your case.
public static String readLineWithFinally() {
System.out.println("Starting readLineWithFinally method.");
try (RandomAccessFile in = new RandomAccessFile("products.ran", "r")) {
return in.readLine();
} catch (IOException e) {
System.out.println(e.toString());
return null;
}
}
You'll also want to be certain that your usage is consistent with what the API mandates for RandomAccessFile.
The code that you posted shouldn't compile, as RandomFile(String, String) can possibly throw FileNotFoundException. As such, we must include it in the try block.
System.out.println("Starting readLineWithFinally method.");
RandomAccessFile in = null;
try {
in = new RandomAccessFile("products.ran", "r");
String s = in.readLine();
return s;
} catch (IOException e) {
System.out.println(e.toString());
return null;
} finally {
try {
if(in != null) {
in.close();
}
} catch (Exception e) {
System.out.println("Generic Error Message");
}
}
Keep in mind the file name and path are fake but here is what I have:
That is why you will have a FileNotFoundException while creating RandomAccessFile("products.ran", "r") with read access mode "r".
From the documentation: RandomAccessFile(String name, String mode)
This constructor throws a FileNotFoundException if the mode is
"r" but the given string does not denote an existing regular file,
or if the mode begins with "rw" but the given string does not denote
an existing, writable regular file and a new regular file of that name
cannot be created, or if some other error occurs while opening or
creating the file
Eclipse (Juno) gives the following warning:
Potential resource leak: 'os' may not be closed
at the first line of the try body in this code:
static void saveDetails(byte[] detailsData) {
OutputStream os = null;
try {
os = sContext.openFileOutput(DETAILS_FILE_NAME, Context.MODE_PRIVATE);
os.write(detailsData);
} catch (IOException e) {
Log.w(LOG_TAG, "Unable to save details", e);
} finally {
if (os != null) {
try {
os.close();
} catch (IOException ignored) {
}
}
}
}
The method openFileOutput is declared to throw a FileNotFoundException.
Is this a false positive? It seems like a fairly vanilla execution path analysis.
In my opinion, this is a false positive. Your resource is closed in a "finally" block, so I cannot see what could go wrong here.
As a sidenote, if you are using Java 7, I'd recommend using the "try-with-resources" idiom.
static void saveDetails(byte[] detailsData) {
try (OutputStream os = sContext.openFileOutput(DETAILS_FILE_NAME, Context.MODE_PRIVATE);) {
os = sContext.openFileOutput(DETAILS_FILE_NAME, Context.MODE_PRIVATE);
os.write(detailsData);
} catch (IOException e) {
Log.w(LOG_TAG, "Unable to save details", e);
}
}
What if you move both open and close to first try clause? They throw the same type of exception. And remove the if os != null.
My guess is it's because you have if (os != null) before closing. Since it's conditional it's possible that the OutputStream is not closed.
What happens if you try:
static void saveDetails(byte[] detailsData) {
OutputStream os = null;
try {
os = sContext.openFileOutput(DETAILS_FILE_NAME, Context.MODE_PRIVATE);
os.write(detailsData);
} catch (IOException e) {
Log.w(LOG_TAG, "Unable to save details", e);
} finally {
try {
os.close();
} catch (IOException ignored) {
}
}
}