Skip to content

Commit f68341f

Browse files
jeremiahjstaceykwwall
authored andcommitted
JavaLogFactory Thread Safety #286 (#470)
* JavaLogFactory Concurrency Test Test case showing that in multi-threaded requests for a single reference, multiple Logger references may be created. * Logic & Test Updates JavaLogFactory Extending test to also create Logs by module name. Updating logic in class to have class delegate to the module name with the class name reference and synchronizing on the map while the reference is being retrieved and/or created.
1 parent c34eeaa commit f68341f

File tree

2 files changed

+84
-17
lines changed

2 files changed

+84
-17
lines changed

src/main/java/org/owasp/esapi/reference/JavaLogFactory.java

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -49,30 +49,24 @@ public JavaLogFactory() {}
4949
* {@inheritDoc}
5050
*/
5151
public Logger getLogger(Class clazz) {
52-
53-
// If a logger for this class already exists, we return the same one, otherwise we create a new one.
54-
Logger classLogger = (Logger) loggersMap.get(clazz);
55-
56-
if (classLogger == null) {
57-
classLogger = new JavaLogger(clazz.getName());
58-
loggersMap.put(clazz, classLogger);
59-
}
60-
return classLogger;
52+
return getLogger(clazz.getName());
6153
}
6254

6355
/**
6456
* {@inheritDoc}
6557
*/
6658
public Logger getLogger(String moduleName) {
6759

68-
// If a logger for this module already exists, we return the same one, otherwise we create a new one.
69-
Logger moduleLogger = (Logger) loggersMap.get(moduleName);
70-
71-
if (moduleLogger == null) {
72-
moduleLogger = new JavaLogger(moduleName);
73-
loggersMap.put(moduleName, moduleLogger);
74-
}
75-
return moduleLogger;
60+
synchronized (loggersMap) {
61+
// If a logger for this module already exists, we return the same one, otherwise we create a new one.
62+
Logger moduleLogger = (Logger) loggersMap.get(moduleName);
63+
64+
if (moduleLogger == null) {
65+
moduleLogger = new JavaLogger(moduleName);
66+
loggersMap.put(moduleName, moduleLogger);
67+
}
68+
return moduleLogger;
69+
}
7670
}
7771

7872

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package org.owasp.esapi.reference;
2+
3+
import java.util.ArrayList;
4+
import java.util.HashSet;
5+
import java.util.List;
6+
import java.util.Set;
7+
import java.util.concurrent.ConcurrentHashMap;
8+
import java.util.concurrent.CountDownLatch;
9+
10+
import org.junit.Assert;
11+
import org.junit.Test;
12+
import org.owasp.esapi.Logger;
13+
14+
15+
public class JavaLogFactoryTest {
16+
17+
@Test
18+
public void testConcurrentLogRequest() throws InterruptedException {
19+
final ConcurrentHashMap<Integer, Logger> logCapture = new ConcurrentHashMap<>();
20+
List<Thread> threads = new ArrayList<>();
21+
final CountDownLatch forceConcurrency = new CountDownLatch(1);
22+
for (int x = 0 ; x < 10; x ++) {
23+
final int requestIndex = x;
24+
Runnable requestLogByClass = new Runnable() {
25+
@Override
26+
public void run() {
27+
try {
28+
forceConcurrency.await();
29+
} catch (InterruptedException e) {
30+
// TODO Auto-generated catch block
31+
e.printStackTrace();
32+
}
33+
logCapture.put(requestIndex, JavaLogFactory.getInstance().getLogger(JavaLogFactoryTest.class));
34+
}
35+
};
36+
37+
Runnable requestLogByModule = new Runnable() {
38+
@Override
39+
public void run() {
40+
try {
41+
forceConcurrency.await();
42+
} catch (InterruptedException e) {
43+
// TODO Auto-generated catch block
44+
e.printStackTrace();
45+
}
46+
logCapture.put(requestIndex, JavaLogFactory.getInstance().getLogger(JavaLogFactoryTest.class.getName()));
47+
}
48+
};
49+
50+
threads.add(new Thread(requestLogByClass, "Request Log By Class " + x));
51+
52+
threads.add(new Thread(requestLogByModule, "Request Log By Name " + x));
53+
54+
55+
}
56+
57+
for (Thread thread : threads) {
58+
thread.start();
59+
}
60+
61+
forceConcurrency.countDown();
62+
63+
for (Thread thread: threads) {
64+
thread.join();
65+
}
66+
67+
68+
Set<Logger> uniqueLoggers = new HashSet<>(logCapture.values());
69+
70+
Assert.assertEquals(1, uniqueLoggers.size());
71+
72+
}
73+
}

0 commit comments

Comments
 (0)