Solved

null pointer exception -- object instantiation problem??

Posted on 2003-11-23
20
288 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
Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
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

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

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 62
simple java question 3 59
session migration servlets 2 42
fibonacci ten numbers 4 45
For customizing the look of your lightweight component and making it look lucid like it was made of glass. Or: how to make your component more Apple-ish ;) This tip assumes your component to be of rectangular shape and completely opaque. (COD…
This was posted to the Netbeans forum a Feb, 2010 and I also sent it to Verisign. Who didn't help much in my struggles to get my application signed. ------------------------- Start The idea here is to target your cell phones with the correct…
Viewers learn about the “for” loop and how it works in Java. By comparing it to the while loop learned before, viewers can make the transition easily. You will learn about the formatting of the for loop as we write a program that prints even numbers…
Viewers will learn about the different types of variables in Java and how to declare them. Decide the type of variable desired: Put the keyword corresponding to the type of variable in front of the variable name: Use the equal sign to assign a v…

791 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