WICKET-6169 NullPointerException accessing AbstractRequestLogger.getLiveSessions


Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/0a6a96bc
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/0a6a96bc
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/0a6a96bc

Branch: refs/heads/WICKET-6183
Commit: 0a6a96bcbf42b7d4a31065c23fa36260b454f371
Parents: be7cd7c
Author: Martin Tzvetanov Grigorov <[email protected]>
Authored: Sat May 21 13:09:17 2016 +0200
Committer: Andrea Del Bene <[email protected]>
Committed: Fri May 27 13:12:16 2016 +0200

----------------------------------------------------------------------
 .../protocol/http/AbstractRequestLogger.java    |   3 +-
 .../http/RequestLoggerLiveSessionsTest.java     | 123 +++++++++++++++++++
 2 files changed, 124 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/0a6a96bc/wicket-core/src/main/java/org/apache/wicket/protocol/http/AbstractRequestLogger.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/protocol/http/AbstractRequestLogger.java
 
b/wicket-core/src/main/java/org/apache/wicket/protocol/http/AbstractRequestLogger.java
index 0c5d7d0..8cb8fcd 100644
--- 
a/wicket-core/src/main/java/org/apache/wicket/protocol/http/AbstractRequestLogger.java
+++ 
b/wicket-core/src/main/java/org/apache/wicket/protocol/http/AbstractRequestLogger.java
@@ -134,8 +134,7 @@ public abstract class AbstractRequestLogger implements 
IRequestLogger
        @Override
        public SessionData[] getLiveSessions()
        {
-               final SessionData[] sessions = liveSessions.values().toArray(
-                       new SessionData[liveSessions.values().size()]);
+               final SessionData[] sessions = 
liveSessions.values().toArray(new SessionData[0]);
                Arrays.sort(sessions);
                return sessions;
        }

http://git-wip-us.apache.org/repos/asf/wicket/blob/0a6a96bc/wicket-core/src/test/java/org/apache/wicket/protocol/http/RequestLoggerLiveSessionsTest.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/protocol/http/RequestLoggerLiveSessionsTest.java
 
b/wicket-core/src/test/java/org/apache/wicket/protocol/http/RequestLoggerLiveSessionsTest.java
new file mode 100644
index 0000000..edbc552
--- /dev/null
+++ 
b/wicket-core/src/test/java/org/apache/wicket/protocol/http/RequestLoggerLiveSessionsTest.java
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.protocol.http;
+
+import org.apache.wicket.util.SlowTests;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import java.util.ArrayList;
+import java.util.Random;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Test for https://issues.apache.org/jira/browse/WICKET-6169
+ */
+@Category(SlowTests.class)
+public class RequestLoggerLiveSessionsTest 
+{
+       private final RequestLogger requestLogger = new RequestLogger();
+       
+       private final ArrayList<String> sessionIds = new ArrayList<>();
+
+       @Test
+       public void concurrentModification() {
+               SessionCreateThread sct = new SessionCreateThread();
+               SessionDestroyThread sdt = new SessionDestroyThread();
+               sct.start();
+               sdt.start();
+               AtomicBoolean nullPointerExceptionThrown = new 
AtomicBoolean(false);
+
+               int count = 10000000;
+
+               while (count-- > 0)
+               {
+                       try {
+                               requestLogger.getLiveSessions();
+                       }
+                       catch (NullPointerException e)
+                       {
+                               e.printStackTrace();
+                               nullPointerExceptionThrown.set(true);
+                               break;
+                       }
+               }
+
+               sct.interrupt();
+               sdt.interrupt();
+
+               if (nullPointerExceptionThrown.get()) {
+                       Assert.fail("The test should not fail with 
NullPointerException");
+               }
+       }
+       
+       private class SessionCreateThread extends Thread
+       {
+               private final Random random = new Random();
+               
+               public void run()
+               {
+                       while (!isInterrupted())
+                       {
+                               if (sessionIds.size() < 50)
+                               {
+                                       String sessionId = 
UUID.randomUUID().toString();
+                                       synchronized (sessionIds) {
+                                               sessionIds.add(sessionId);
+                                       }
+                                       requestLogger.sessionCreated(sessionId);
+                               }
+                               
+                               try
+                               {
+                                       Thread.sleep(random.nextInt(20));
+                               }
+                                       catch (InterruptedException e) {
+                               }
+                       }
+               }
+       }
+
+       private class SessionDestroyThread extends Thread
+       {
+               private final Random random = new Random();
+               
+               public void run()
+               {
+                       while (!isInterrupted())
+                       {
+                               if (sessionIds.size() > 0)
+                               {
+                                       String sessionId = 
sessionIds.get(random.nextInt(sessionIds.size()));
+                                       
requestLogger.sessionDestroyed(sessionId);
+                                       synchronized (sessionIds) {
+                                               sessionIds.remove(sessionId);
+                                       }
+                               }
+                               
+                               try
+                               {
+                                       Thread.sleep(random.nextInt(20));
+                               }
+                                       catch (InterruptedException e) {
+                               }
+                       }
+               }
+       }
+}

Reply via email to