#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2012
    Posts
    7
    Rep Power
    0

    I get the error Exception in thread "main" java.lang.NullPointerException?


    Hi all;

    I'm new to java.

    I have a program that is intented to get a text file (in here,ScanTest.txt) containing some names and values such as:

    name=jeremy
    #This is a comment
    account=1234
    balance=500
    ....

    The line starting with "#" is considered as a comment.

    Then, I have a method called "getString" so that if I give a name to it, it should return corresponding value as following:

    name---->jeremy
    balance---->500

    To implement this program, I've used "hashtable" class. Here is my code:
    Code:
    package io;
    
    import java.io.*;
    import java.util.*;
    
    public class HashTableDemo {
        static String fileName;
        static Hashtable hash;
        static Enumeration names;
        
        public HashTableDemo() {
            fileName = "D:\\Documents and Settings\\Bahareh\\Desktop\\ScanText.txt"; 
            hash = new Hashtable();
        }
        public static String getString(String st)
        {
           return (String)hash.get(st); 
        }
    
        public static void main(String args[]) throws Exception{
            // Create a hash map
            //Hashtable hash = new Hashtable();
            try{
             String st;
            InputStream in = new FileInputStream(fileName);
            Scanner sc = new Scanner(in).useDelimiter("=");
            while (sc.hasNext()) {
                hash.put(sc.next(), sc.next());
            }
            // Show all hashes in hash table.
            names = hash.keys();
            while (names.hasMoreElements()) {
                str = (String) names.nextElement();
                System.out.println(str + ": "+ /*hash.get(str)*/getString(str));
            }
            System.out.println();
            }
            catch(IOException e)
            {
               System.out.print(e.getMessage());
            }
            }
        }
    When I run it, I get the error:
    ------------------------------------------------------
    Exception in thread "main" java.lang.NullPointerException
    at java.io.FileInputStream.<init>(FileInputStream.java:134)
    at java.io.FileInputStream.<init>(FileInputStream.java:97)
    at io.HashTableDemo.main(HashTableDemo.java:29)
    Java Result: 1
    BUILD SUCCESSFUL (total time: 2 seconds)
    ------------------------------------------------------

    What's the problem?

    Besides, I want to ignore the lines starting with "#" sign and not to add them to the hash table.

    How should I seperate these lines?
    How does java recognize that first character of a line is "#" sign?

    Please help...

    TIA
  2. #2
  3. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2013
    Location
    Saint-Petersburg, Russia
    Posts
    237
    Rep Power
    29
    Hi!

    You get null pointer exception - as you can see from description of the error - in the line #29 where you are trying to open the file.

    It is because fileName variable contains null. It was not initialized.

    You are trying to assign value to it in the constructor, but the constructor is never called since you are working within "main" method which is static.

    Think of some other place to move this initialization to.

    I have few more hints for you:
    1. Use HashMap instead of HashTable (which is really old).
    2. As a matter of fact you need not any of these at all, since your file is in "properties file format". Here is java.util.Properties class (based on Hashtable) which has methods for bulk read from file.
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2012
    Posts
    7
    Rep Power
    0
    Thanks for your reply.

    Yes, using the properties class is fine.
    To correct this code, I should seperate the main class and the getString class. That is, I should have two classes and call getString class in main class.
    Am I right?

    Thanks again for your hint.
  6. #4
  7. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2013
    Location
    Saint-Petersburg, Russia
    Posts
    237
    Rep Power
    29
    To correct this code, I should seperate the main class and the getString class
    If you put hashtable (or hashmap or properties) structure and getString method into separate class, you can succeed. And this would be more logical, I think.

    Though core of the problem is not how you place your code, but that certain lines (those two in constructor) are never get called with the approach you used to organize your code in static methods.

    (so easiest way to fix is simply to move these two lines to main from constructor - though separation you proposed is more preferable).
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2012
    Posts
    7
    Rep Power
    0
    I corrected the code as following:
    Code:
    package io;
    
    import java.io.*;
    import java.util.*;
    
    public class MyHashTable 
    {
        static String fileName;
        static Hashtable hash;
        static Enumeration names;
    
        public HashTableDemo() {
            fileName = "D:\\Documents and Settings\\Bahareh\\Desktop\\ScanText.txt";
            hash = new Hashtable();
        }
    
        public static String getString(String st) {
            return (String) hash.get(st);
        }
    
    )
    
    public class HashTableDemo 
    {
    
            public static void main(String args[]) throws Exception {
                // Create a hash map
                //Hashtable hash = new Hashtable();
                try {
                    MyHashTable ht = new MyHashTable();
                    String st;
                    InputStream in = new FileInputStream(ht.filename);
                    Scanner sc = new Scanner(in).useDelimiter("=");
                    while (sc.hasNext()) {
                        ht.hash.put(sc.next(), sc.next());
                    }
                    // Show all hashes in hash table.
                    ht.names = ht.hash.keys();
                    while (ht.names.hasMoreElements()) {
                        str = (String) ht.names.nextElement();
                        System.out.println(str + ": " + /*hash.get(str)*/ ht.getString(str));
                    }
                    System.out.println();
                } catch (IOException e) {
                    System.out.print(e.getMessage());
                }
            }
        }
    But when I run this code, I get a dialog box with "class io.HashTableDemo" does not have a main method" statement!!!

    What's wrong with this code?

    And what about this problem:

    I want to ignore the lines starting with "#" sign and not to add them to the hash table.

    How should I seperate these lines?
    How does java recognize that first character of a line is "#" sign?
  10. #6
  11. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2013
    Location
    Saint-Petersburg, Russia
    Posts
    237
    Rep Power
    29
    But when I run this code, I get a dialog box with "class io.HashTableDemo" does not have a main method" statement!!!
    Strange that you give this error and not the other. The main problem is that you could not have two public classes in one file. Each public class should be put into the file with the same name.

    And what about this problem:
    With your approach it is really problem.
    You'd better create Scanner without special delimiter and use method "nextLine" to read the whole line inside a loop.
    Then you can check for # sign with startsWith method of a String class - and skip the line if necessary.
    You also will need to skip if the line isEmpty.

    If line is not skipped, use split() method of the class String to split it by "=" character into two parts - and put them into hashtable.

    As I told earlier, if you change to using "Properties" class, all these things are already implemented in it and you will need only call method load() passing it your file.
  12. #7
  13. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2012
    Posts
    7
    Rep Power
    0
    Dear rodiongork,

    I changed the code and it run. but now, I want to skip the lines starting with "#" sign. So I use "startWith" method, but when runnig the code, I see error:

    Exception in thread "main" java.util.NoSuchElementException
    at java.util.Scanner.throwFor(Scanner.java:907)
    at java.util.Scanner.next(Scanner.java:1416)
    at io.HashTableDemo.main(MyHashTable.java:41)
    Java Result: 1

    Here is the code:
    Code:
    package io;
    
    import java.io.*;
    import java.util.*;
    
    public class MyHashTable 
    {
        static String fileName;
        static Hashtable hash;
        static Enumeration names;
    
        public MyHashTable() {
            fileName = "D:\\Documents and Settings\\Bahareh\\Desktop\\ScanTest.txt";
            hash = new Hashtable();
        }
    
        public static String getString(String st) {
            return (String) hash.get(st);
        }
    }
    
    class HashTableDemo 
    {
    
            public static void main(String args[]) throws Exception {
                // Create a hash map
                //Hashtable hash = new Hashtable();
                try {
                    MyHashTable ht = new MyHashTable();
                    String str;
                    InputStream in = new FileInputStream(ht.fileName);
                    Scanner sc = new Scanner(in).useDelimiter("=");
                    while (sc.hasNextLine()) {
                        if( sc.next().startsWith("#"))
                            System.out.println("start with #");
                        else
                            ht.hash.put(sc.next(), sc.next());
                    }
                    // Show all hashes in hash table.
                    ht.names = ht.hash.keys();
                    while (ht.names.hasMoreElements()) {
                        str = (String) ht.names.nextElement();
                        System.out.println(str + ": " + /*hash.get(str)*/ ht.getString(str));
                    }
                    System.out.println();
                } catch (IOException e) {
                    System.out.print(e.getMessage());
                }
            }
        }
    The problem is because this part:

    while (sc.hasNextLine()) {
    if( sc.next().startsWith("#"))
    System.out.println("start with #");
    else
    ht.hash.put(sc.next(), sc.next());
    }

    How should I fix this?

    Could you run my code in NetBeans and correct that?
    I so much appreciate you...
  14. #8
  15. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2013
    Location
    Saint-Petersburg, Russia
    Posts
    237
    Rep Power
    29
    I want to skip the lines starting with "#" sign.
    Try to rewrite your code as I hinted before, reading line by line.

    Stop experimenting with scanner splitting with "=" as delimiter. You will get headache trying to eliminate comments in this way (though of course it is possible, but it is really wrong and hard way).
  16. #9
  17. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2013
    Posts
    8
    Rep Power
    0
    Hi creative22 - it's been about a week. Have you made progress?
    I agree with rodiogork's earlier post - just scan the data in once into a string variable once and then do all the checking for the # character with the string variable.

IMN logo majestic logo threadwatch logo seochat tools logo