Solved

null pointer exception -- object instantiation problem??

Posted on 2003-11-23
20
282 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
 
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
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 
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

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

Introduction Java can be integrated with native programs using an interface called JNI(Java Native Interface). Native programs are programs which can directly run on the processor. JNI is simply a naming and calling convention so that the JVM (Java…
Introduction This article is the second of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers the basic installation and configuration of the test automation tools used by…
This theoretical tutorial explains exceptions, reasons for exceptions, different categories of exception and exception hierarchy.
This tutorial will introduce the viewer to VisualVM for the Java platform application. This video explains an example program and covers the Overview, Monitor, and Heap Dump tabs.

746 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

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now