Description
Hello, I am a software tester. I found this problem in all versions of log4j. AppenderSkeleton may cause a NullPointerException error.
//Error code fragment
public boolean isAsSevereAsThreshold(Priority priority)
public void setThreshold(Priority threshold)
{ this.threshold = threshold; }
In the AppenderSkeleton class, if the isAsSevereAsThreshold() method and setThreshold are executed simultaneously by two threads, isAsSevereAsThreshold method checks that this.threshold is not null, another thread calls the setThreshold method and sets the threshold to null. When the thread switches back to the isAsSevereAsThreshold method to continue execution, it will trigger a NullPointerException.
There are many classes that extends AppenderSkeleton, which can cause this error if they are interleaved by different threads.
This is an atomic violation.
This error can be triggered by the following test:
public static void main(String[] args) throws Exception {
AppenderSkeleton app = new NullAppender();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 90000;i++)
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 90000;i++)
}
});
t1.start();
t2.start();
t1.join();
t2.join();
}
Error message:
Exception in thread "Thread-0" java.lang.NullPointerException
at org.apache.log4j.Priority.isGreaterOrEqual(Priority.java:123)
at org.apache.log4j.AppenderSkeleton.isAsSevereAsThreshold(AppenderSkeleton.java:219)
at test.TestSequence$1.run(TestSequence.java:19)
at java.lang.Thread.run(Thread.java:748)