Hello

I am trying to write to a text log file for my world of zuul game. I have created a Class Logger to write into the file, here is the code:

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

public class Logger
{
    private BufferedWriter out;
       public Logger() throws IOException
    {
        //
        fw = new FileWriter("logfile.txt");
        //
        bw = new BufferedWriter(fw);              
    }

    public void logToFile(String input) throws IOException
    {
        this.input = input;
        bw.write("User Input:  " + input + "\n");     
    }

    public void closeStream()
    {
        bw.close();
    }
}

in the main Game class, I have added this bit to write into the file:

public void play() 
    {            
        printWelcome();

        // Enter the main command loop.  Here we repeatedly read commands and
        // execute them until the game is over.

        boolean finished = false;
        while (! finished) {
            Command command = parser.getCommand();
            String input = command.getCommandWord() + command.getSecondWord();
            logger.logToFile(input); //i get the error in here!
            finished = processCommand(command);

        }
        logger.closeStream();
        System.out.println("Thank you for playing.  Good bye.");
    }

and when compiling i got this error: unreported exception java.io.exception must be caught or declared to be thrown.

Not sure what it means! any help would be much appreciated!

Exceptions which are not RuntimeExceptions must be handled explicitly. They cannot be ignored. A method where an Exception may occur can either declare it to be thrown, or catch it. You catch an exception by using something like:

try
{
    methodThatMightThrowExceptionA();
}
catch(ExceptionA e)
{
    whatIWantToDoIfExceptionAHappens();
}

You know that ExceptionA might be thrown from methodThatMightThrowExceptionA because its declaration includes throws ExceptionA. And if you don't want to catch your exception, then you can do that too. Like this:

public void methodThatDoesNotCatch() throws ExceptionA
{
    methodThatMightThrowExceptionA();
}

This method does not have to catch the exception because it is declared to throw the exception, but now anyone who calls methodThatDoesNotCatch() will have to deal with ExceptionA somehow. This is all for the purpose of keeping track of where exceptions might come from and who is responsible for recovering from exceptions. Of course java.lang.RuntimeException and its subclass exceptions are exempt from this rule; they can be thrown anywhere with no requirements to declare or catch them.

So when you see that an exception must be caught or declared to be thrown, that is what it is talking about.

Edited 3 Years Ago by bguild

I have followed your explanation, and the program compiled, but now it is throwing a nullpointerexception error in the main class Game:

boolean finished = false;
        while (! finished) {
            Command command = parser.getCommand();
            String input = command.getCommandWord() + command.getSecondWord();
            logger.logToFile(input); //the error
            finished = processCommand(command);

        }
        logger.closeStream();
        System.out.println("Thank you for playing.  Good bye.");
}

i have added try and catch for both the writing and closing of the file in the logger class. 

from what i understand about the error, it means that I am passing a null to the logger.lotToFile(input) method, but not sure why!

thank you for the help!

Next time, please copy & paste the error shown by runtime. Your assumption may be correct, but it may be incorrect under certain circumstances.

If you look at the method in Logger class, there is a variable this.input inside the method. The variable input and this.input are not the same. The input is a local variable seen by the method. The this.input is the class variable that can be seen by the whole class. Have you ever declared the class's variable called input in the class?

Edited 3 Years Ago by Taywin

Taywin: I still dont get it! I have declared input in the class! not sure what to do,,, :(

thanks tux4life! as I have worked with the Logger now, I think I will continue with it,,,

This is your current class...

public class Logger {
  private BufferedWriter out;
  public Logger() throws IOException {
    fw = new FileWriter("logfile.txt");
    bw = new BufferedWriter(fw);
  }

  public void logToFile(String input) throws IOException {
    this.input = input;   // <--- Where did you declare 'input' variable of the class?
    bw.write("User Input: " + input + "\n");
  }

  public void closeStream() {
    bw.close();
  }
}

PS: This is not JavaScript that you can simply intialize object/class's variable on the fly.

Edited 3 Years Ago by Taywin

this is the source code for logger:

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

/**
 * Write a description of class Logger here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Logger
{
    // instance variables - replace the example below with your own
    private BufferedWriter bw;
    private String input;  //declared in here


    /**
     * Constructor for objects of class Logger
     */
    public Logger() throws IOException
    {
        //
        FileWriter fw = new FileWriter("logfile.txt");

        //
        BufferedWriter bw = new BufferedWriter(fw);


    }

    /**
     * 



     */
    public void logToFile(String input) 
    {
        this.input = input;
        try
        {

            bw.write("User Input:  " + input + "\n");
            // put your code here
        }
        catch (IOException ioe)
        {
            ioe.printStackTrace();
        }
    }


    public void closeStream()
     {
        try
        {
        bw.close();
        }
        catch (IOException ioe)
        {
        ioe.printStackTrace();
        }
    }
}

That looks different from what you posted earlier.

Anyway, passing null value, but later concatenating it with String won't cause the NPE. You still have not posted the exact exception/error you got from running your program... What exactly error it shows?

If you have already declared the variable, then what getCommand() returns?

Command command = parser.getCommand();

Is it possible that the method returns null value?

the exact error is:
java.lang.NullPpointerException:
null

Command command = parser.getCommand(); returns an object command of class Command, and getCommandWord() and getSecondWord() return strings. They shouldnt be returning null as the program was working before adding the logger bit!

Nope, I'm talking about parser.getCommand() which may return null or something is wrong in there. The NPE could actually comes from using null to call getCommandWord(). That's my suspicious.

By the way, the exact error should also tells you which line the error occurs. If you are not sure, add System.out.println() to see where your program stops at...

public void logToFile(String input) {
  System.out.println("In logToFile()");
  this.input = input;
  try {
    System.out.println("In try");
    bw.write("User Input: " + input + "\n");
    System.out.println("Pass the try");
  // put your code here
  }
  catch (IOException ioe) {
    System.out.println("Failed, in IOException");
    ioe.printStackTrace();
  }
  catch (Exception e) {  // I add this to catch all other Exception
    System.out.println("Unknow exception thrown!");
    e.printStackTrace();
  }
}


boolean finished = false;
System.out.println("Start checking");
while (! finished) {
  System.out.println("Not done");
  Command command = parser.getCommand();
  System.out.println("Got command: "+(command==null ? "NULL" : "OK"));
  String input = command.getCommandWord() + command.getSecondWord();
  System.out.println("Got input: "+(input==null ? "NULL" : "OK"));
  logger.logToFile(input); //the error
  System.out.println("Logged successfully");
  finished = processCommand(command);
  System.out.println("Recheck again");
}
System.out.println("Closing the stream");
logger.closeStream();
System.out.println("Closed the stream");
System.out.println("Thank you for playing. Good bye.");

PS: You should use this System.out.println() technique to debug your code if you do not use any luxurious IDE or you don't know how to use the debug feature in an IDE.

Edited 3 Years Ago by Taywin

it is a very smart way! i added a print out for the "input" string, i got this:

You are outside the main entrance of the university.
Exits:  south east west
sTARET CHECKING
NOT DONE
> go south
got command: OK
Got input: OK
gosouth

the error line:

Command command = parser.getCommand();
            System.out.println("got command: "+ (command==null ? "NULL" : "OK"));
            String input = command.getCommandWord() + command.getSecondWord();
            System.out.println("Got input: "+(input==null ? "NULL" : "OK"));
            System.out.println(input);
            logger.logToFile(input); // here is the error
            System.out.println("Logged successfully");
            finished = processCommand(command);
            System.out.println("Recheck again");

even when I removed logger.logToFile(input); and kept the .close(); line, i got the same error!
no, the Logger instance wasnt initiated @_@'' !!! thanks Taywin :)

for some reason, I get "unknown exception thrown" should I get red of 
catch (Exception e) {
.....
}
? or something else went wrong? I still dont know where the file is saved!

So what stack trace is printed? Also, does your program have permission to create/write a file in the folder/directory your program is running?

is this the stack trace:
"t __SHELL1.run(__SHELL1.java:8)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at bluej.runtime.ExecServer$3.run(ExecServer.java:725)" ?

I dont know if it has the permission! didnt do anything about that,,,

Just take a look at BufferedWriter class... There is no such a method write(String) but rather write(String, int, int)...

PS: When you ask others to help you debugging, please post all the exception thrown from your program. It is not easy and could be inaccurate to assume what's going wrong in your program. Only code is not enough. Your own analysis is even worse. If your analysis is correct, you would not be asking questions...

This article has been dead for over six months. Start a new discussion instead.