Hi,

> -----Original Message-----
> From: stacy.ma...@csiro.au [mailto:stacy.ma...@csiro.au]
> Sent: Thursday, May 1, 2014 12:45 PM
> 
> Hi all,
> 
> Just starting out with Tomcat v7.0.53, running under Java SE 1.7.0_51 with
> Mac OSX 10.9. I am writing a chat application using websockets. I have a
> method getUserNames() which allows me to list all logged on users via
> Session chatroomUsers:
> 
>  static Set<Session> chatroomUsers = Collections.synchronizedSet(new
> HashSet<Session>());
> 
> The method is:
> 
>        private Set<String> getUserNames() {
>             HashSet<String> returnSet = new HashSet<String>();
>             Iterator<Session> iterator = chatroomUsers.iterator();
>             while (iterator.hasNext())
> returnSet.add(iterator.next().getUserProperties().get("username").toString
> ());
>             return returnSet;
>     }
> 
> When I compile this under Eclipse, Tomcat reports the following:
> 
> 
> May 01, 2014 8:30:34 PM
> org.apache.tomcat.websocket.pojo.PojoEndpointBase onError
> SEVERE: No error handling configured for [ChatroomServerEndpoint] and the
> following error occurred
> java.lang.NullPointerException
>     at
> ChatroomServerEndpoint.getUserNames(ChatroomServerEndpoint.java:69)
>     at
> ChatroomServerEndpoint.buildJsonUsersData(ChatroomServerEndpoint.java
> :53)
>     at
> ChatroomServerEndpoint.handleOpen(ChatroomServerEndpoint.java:29)
> 
> Now if I uncomment the while loop in getUserNames(), everything works
> fine, just no users are added to the logged on list on the chat. I'm not sure 
> if
> the issue is with org.apache.tomcat.websocket.pojo.PojoEndpointBase
> (onError), or perhaps that fact that given there are no users logged on, my
> syntax in the while loop is causing the NullPointerException?
> 
> Any ideas appreciated!

Please post all relevant code. My guess would be that you don't set the 
"username" variable in the session.getUserProperties() Map correctly before 
adding it to the Set so that it throws a NPE, but we would need to see the code 
for that.

Also, there might be an race condition when one thread takes the Session from 
the map and then pauses, and in the meanwhile that session is closed, as the 
Javadoc for Session.getUserProperties() says:
  "The developer may retrieve information from this Map at any time between the 
opening of the session and during the onClose() method. But outside that time, 
any information stored using this Map may no longer be kept by the container. "
In this case, it could be that when the paused thread continues, that it cannot 
access the Map any more (but I'm not sure if this happens with Tomcat).

E.g., the Tomcat Chat Websocket Example [1] stores instances of the 
"ChatAnnotation" in a static Set, as a new instance of such class is created 
for every session, so it can be used to store session-specific variables.


Additional note:
When you iterate over a Set that is returned by Collections.synchronizedSet(), 
you need to manually synchronize over the Set to avoid non-deterministic 
behavior - see [2].


Regards,
Konstantin Preißer


[1] 
http://svn.apache.org/viewvc/tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/chat/
[2] 
http://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#synchronizedSet-java.util.Set-


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to