Solved

null pointer exception -- object instantiation problem??

Posted on 2003-11-23
20
286 Views
Last Modified: 2010-03-31
For what I have, please refer to:
http://www.experts-exchange.com/Programming/Programming_Languages/Java/Q_20805617.html

I have a problem where when I test the program with "type == 2" which goes through sendToOne() method in Server class, I get a NullPointerException at:

ServerThread.run() line94 -------------> server.sendToOne(distributeMessage.substring(2));
Server.sendToOne() line118 ------------>int r = scBack.write(buffer);

I declared a local ByteBuffer at the top of both methods to clear the buffer used in those methods.   Still, NullPointerException is thrown.   One possibility I think what's causing the error is the way I deal with the methods in DataHandler class, namely, addSocketChannel() and addUserInfo().   In particular, addSocketChannel() need to be invoked first to add an instance of SocketChannel into a LinkedList and this LinkedList is used when the latter addUserInfo() is called.   Since I call addUserInfo() at the Clinet constructor and addSocketChannel() at the Server constructor, the ordering of invokation might not seem to be a problem but the Server calls addSocketChannel() after there is an incoming request for connection meaning that by that time, Clinet is processed.   Also if I moved addSocketChannel() to right before the invokation of addUserInfo() in Clinet instead, there is no NullPointer but none of the test System.out outputs are printed.   Another possibility is that I have two instances of DataHandler object in Clinet and Server which they are both trying to access the same data.   Can this be a problem as well?   Since neither Client nor Server can access each other, if this causes a problem do I need to have a connection to a database to store the data which DataHandler is handling?   Even though it is indicated where the problem is caused, so far I find no effective method of tracking where in the transfer process or data storage something is going wrong.   Please give me a suggestion if someone can guide me in fixing this problem.   Thanks.  
0
Comment
Question by:skyblue01
  • 11
  • 9
20 Comments
 
LVL 92

Expert Comment

by:objects
ID: 9808984
scBack must be null.
0
 
LVL 92

Expert Comment

by:objects
ID: 9808996
addUserInfo() is never called on the server, so privateChannles is never populated.
0
 

Author Comment

by:skyblue01
ID: 9809014
>addUserInfo() is never called on the server, so privateChannles is never populated.

The user info, such as username, groupname can only be retreived from the Clinet GUI.   So those information are not available for class Server (and cannot instantiate Client in Server since that would start another session for another user...)   This is the problem I was pointing out.   Is there a way to solve this while preserving the DataHandler class or this whole structure simply does not work?   Please give me your opinion.  
0
Gigs: Get Your Project Delivered by an Expert

Select from freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely and get projects done right.

 
LVL 92

Accepted Solution

by:
objects earned 350 total points
ID: 9809033
You need some way on the server to map which connections correspond to what user, perhaps the user details info should be passed from the client to the server when it connects.
0
 

Author Comment

by:skyblue01
ID: 9809066
But if Server is started first to listen for incoming connection, then in Clinet class if I want to have the user info passed from the Clinet to the Server when it connects, it will have another Server running, wouldn't it?  
0
 
LVL 92

Expert Comment

by:objects
ID: 9809090
I don't see why. Why do u think that?
0
 

Author Comment

by:skyblue01
ID: 9809108
By "passing from Client to Server", don't you mean that you'll do something like:

// Client
Server server = new Server(username, groupname, socketchannel...)

or

server.setInfo(username, groupname, socketchannel...)

Then for every instance of Ciient, an instance of Server will be created though I have one Server hanling all Client connections...
0
 
LVL 92

Expert Comment

by:objects
ID: 9809181
No I mean pass the details on the connection, like how you pass messages.
0
 

Author Comment

by:skyblue01
ID: 9809224
But then I'll need a place to store the data (such as DataHandler) for function like private chat, where one user specifies which other user it wants to talk to (which entails that when destination user is specified, it also have to get an instance of socketchannels, one from initiating client to the server, and another from destination client to server.   So I don't think just passing the user info would do it.   Also from the way I set up my classes, though Server can keep track of each individual socketchannels and perhaps store it in a Vector or LinkedList, as it receives the passed info, it has no way of identifying which info belongs to which channel...
0
 
LVL 92

Expert Comment

by:objects
ID: 9809232
When the server recieves a private message it needs some way to determine which connection to send that message out on. So whenever a connection is made it needs to provide details about the user that is making that connection.
0
 
LVL 92

Expert Comment

by:objects
ID: 9809236
>  it has no way of identifying which info belongs to which channel...

exactly you need to store that mapping.
0
 

Author Comment

by:skyblue01
ID: 9809337
Appending socketchannel at the end of message in processMessage method in Client, passed all the way to sendToOne method in Serever, which has some sort of Vector that keeps all socketchannels stored when its constructor is called, tokenize received message to get socketchannel, compare it to what's in the Vector from a beginning to an end, if matches, store the associated username and groupname which was also appended in the received message along with the matched socketchannel into a hashtable or something (keyed by socketchannel), then have everything stored in class Server, and finally write into the channel only the message part of the received message.   Would that work?   Although I'm using String message to be passed to sendToOne(), is it possible to have an object like socketchannel being appended to this data perhaps by changing this thing from String into Byte and then after decrypting it retreive the necessary object socketchannel and the string part of message?   Is such conversion or encryption/decryption of string+socketchannel into Byte and then back into string+socketchannel possible??
0
 
LVL 92

Expert Comment

by:objects
ID: 9813967
Not sure I understand what you mean, if you are saying pass the SocketChannel instance over the wire with the message then no.
0
 

Author Comment

by:skyblue01
ID: 9814206
What I mentioned above is the only way I could come up with.   I thought that was what you meant by "pass the details on the connection"...   Could you give me an example of what you mean by that?  
0
 

Author Comment

by:skyblue01
ID: 9814262
Or could you show me how it can be accomplished?
0
 
LVL 92

Expert Comment

by:objects
ID: 9814292
All you need to pass is whatever is needed to identify the user which I assume is the same as being passed with the message to identify who the message needs to go to.
0
 

Author Comment

by:skyblue01
ID: 9814386
Right, what identifies the user is its username and socketchannel.   So I was saying that I want to try doing something like below since data must be sent as bytes through a channel and String must be wrapped to get charbuffer.   But you said I can't do something like this...   Did you mean I can't do the concatenation of message and sc to form a string or this whole idea doesn't work?   I'm a little confused...

// in Clinet.java
private SocketChannel sc;
private String username;
private void processMessage(String message) { // message retrieved from the GUI
        try {
            if (type == 1)
                buffer = encoder.encode(CharBuffer.wrap(type + ":" + message + sc)); // <-------------------sc
            else if (type == 2 || type == 3)
                buffer = encoder.encode(CharBuffer.wrap(type + ":" + destUser + ":" + message + sc)); <--------sc

            int r = sc.write(buffer); // sends it to the server

            while (buffer.hasRemaining()) { // TEST
                int numWritten = sc.write(buffer); // sends it to the server
                buffer.compact(); // TEST
                buffer.flip(); // TEST
            }

            //System.out.println("numWritten at Client: " + numWritten); // TEST

            tf.setText(""); // clears the text input field
        } catch(IOException ie) { System.out.println(ie); }
    }
0
 
LVL 92

Expert Comment

by:objects
ID: 9814427
The server knows which channel a message is coming in from (as that is where it is reading it from), what it needs to know is what channel to send the message to.

Users need to identify themselves when they connect, otherwise the server has no idea which user is on which channel and thus no way to know what channel to send private messages on.

Does that make sense?
0
 

Author Comment

by:skyblue01
ID: 9924572
Hey objects, I solved the problem and came back to this question and figured out that what you told me was exactly right.   I couldn't understand what you meant since your explanation was kind of vague at that time.   I used a hashtable with a userinfo key and storing the received socket channel as its value -- i guess the term "mapping" you used was what confused me but please forgive me for not getting back to you...   And thanks for helping me out.  
0
 
LVL 92

Expert Comment

by:objects
ID: 9924602
I do have problems explaining myself sometimes.
Good to hear you got it solved :)

http://www.objects.com.au/staff/mick
0

Featured Post

Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Application launch issue with Apache Tomcat 5 42
groupNoAdj 7 95
throw exception 21 43
pagenation logic how it is working in my code 1 28
INTRODUCTION Working with files is a moderately common task in Java.  For most projects hard coding the file names, using parameters in configuration files, or using command-line arguments is sufficient.   However, when your application has vi…
Are you developing a Java application and want to create Excel Spreadsheets? You have come to the right place, this article will describe how you can create Excel Spreadsheets from a Java Application. For the purposes of this article, I will be u…
Viewers will learn about if statements in Java and their use The if statement: The condition required to create an if statement: Variations of if statements: An example using if statements:
This video teaches viewers about errors in exception handling.

776 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question