0

I have this java code and caught a nullPointerException when I run it. Through debugging using eclipse, I found out that msiLine parameter is null but I can't find out why.

                String msiAbsolutePath = msiFiles.getAbsolutePath();
                String filePath = msiAbsolutePath.substring(0,msiAbsolutePath.lastIndexOf(File.separator));
                new File(filePath+"/Emboss").mkdir();
                new File(filePath+"/Report").mkdir();
                File files = sort(msiFiles,filePath);

                BufferedReader msiReader = new BufferedReader(new FileReader(files));
                BufferedReader embReader = new BufferedReader(new FileReader(embFiles));
                String[] msiTokens = msiFiles.getName().split("\\.(?=[^\\.]+$)");
                String[] embTokens = embFiles.getName().split("\\.(?=[^\\.]+$)");
                final String msiFileName = msiTokens[0];
                final String embFileName = embTokens[0];
                Date date = new Date();
                DateFormat dateFormatName = new SimpleDateFormat("MMdd");
                PrintWriter msiWrite = new PrintWriter(new BufferedWriter(new FileWriter(filePath+"/Emboss/"+msiFileName+".PRN")));
                PrintWriter embWrite = new PrintWriter(new BufferedWriter(new FileWriter(filePath+"/Emboss/"+embFileName+".PRN")));
                PrintWriter reportWrite = new PrintWriter(new BufferedWriter(new FileWriter(filePath+"/Report/CS"+dateFormatName.format(date)+".RPT")));


                cnt=totalLines=0;
                //String msiLine = msiReader.readLine();
                String msiLine="";
                String embLine = embReader.readLine();
        here>>> for(msiLine = msiReader.readLine(); msiLine.length() >= 60; msiLine = msiReader.readLine())
                {
                    embLine = embReader.readLine();
                    msiWrite.print();
                    :
                    :

                    }
                    statMessage = "Completed " + current + " out of " + lengthOfTask + ".";
                }
                :
                :
            }catch(IllegalStateException | IOException | NullPointerException d){
                d.printStackTrace();
            }
        }
    }

    File sort(File file, String filepath){
        File files = new File(filepath + "\\tempMSIfile.msi");
        try{

            BufferedReader reader = new BufferedReader(new FileReader(file));
            Map<String, String> map=new TreeMap<String, String>();
            String line=reader.readLine();
            for(line = reader.readLine(); line.length() >= 60; line = reader.readLine()){
                map.put(getField(line),line);
            }
            reader.close();
            PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(files)));
            for(String val : map.values()){
                writer.print("" +val);  
                writer.print(NEWLINE);
            }
            writer.close();

        }catch(IllegalStateException | IOException | NullPointerException d){
            LOG.fine("Error, " + d.getMessage());
        }
        return files;
    }

    String getField(String line) {
        return line.substring(10, 26);//extract value you want to sort on
    }

Can somebody explain to me why is the msiLine is null?

I think it involves the File files = sort(msiFiles,filePath); but the eclipse report that files parameter does have the correct file/thing(?) assigned to it.

In case anyone wondering, tempMSIfile.msi is not empty.

Archie
  • 110
  • 7

3 Answers3

3

Reader's .readLine() returns null when the end of input is reached. As such, your condition:

msiLine.length() < 60`

can trigger a NullPointerException. Change it to add a null test before testing the length.

EDIT: as @KubaSpatny points out, change the condition to:

msiLine != null && msiLine.length() < 60

Or, as your comment seems to suggest, put msiLine != null as the condition, and as the first instruction in the loop:

if (msiLine.length() < 60)
    continue; // or break;, depending on what you want to do

Your sort() method suffers the same problem.

fge
  • 119,121
  • 33
  • 254
  • 329
  • Yeah, I've just found out that I need to change it to `msiLine != null`. But I need to use the `msiLine.length() >= 60` because I don't need to read some of the line in the text file such as header and footer which is why I put it >60 because the body has more than 60 char while the header and footer does not. – Archie Feb 11 '14 at 09:39
  • That's what confuse me. The sort() method doesn't have any problem and can write file just fine but using the same loop header for the main class, it caught exception. – Archie Feb 11 '14 at 09:49
  • Well, it means you are lucky, but don't rely on luck ;) – fge Feb 11 '14 at 09:51
  • Yeah, I've just found out why.. My sort() method will create a replica of the original file with the content sorted and without the header and footer, so I just don't need to use the `msiLine.length() >=60` and just change it to `msiLine !=null`.. Problem solved, thanks.. Wow, never been this productive on the internet before.. – Archie Feb 11 '14 at 09:59
2

Read the documentation for readLine():

Returns: A String containing the contents of the line, not including any line-termination characters, or null if the end of the stream has been reached

That means: if msiLine is null inside the loop, the file has been read completely. In that case, exit the loop:

if(msiLine==null){
   break;
}

or add the check to your loop header.

f1sh
  • 11,489
  • 3
  • 25
  • 51
  • I've tried your code inside my loop, but it still caught NullPointerException.. I can only change the loop header to `msiLine != null` but as I said in another comment, I need to check `msiLine.length() >= 60` because I don't want to read header and footer of the text file. – Archie Feb 11 '14 at 09:44
  • But in this case your file has less than 60 lines, which means you read the footer anyways and then run into the NullPointerException. Think about how you can detect the footer, since your files obviously vary in size. – f1sh Feb 11 '14 at 09:46
  • yeah, thanks for your help..My `sort()` method remove the header and footer already so I don't need to use the `>= 60` lines. – Archie Feb 11 '14 at 10:01
0

Javadoc for java.io.BufferedReader#readLine() states that it returns

 A String containing the contents of the line, not including
 any line-termination characters, or null if the end of the
 stream has been reached

You are probably encountering the end of the file. Add a null check for msiLine to check when you reach the end of the file.

Saket
  • 3,079
  • 3
  • 29
  • 48