Skip to content

Commit 7d73278

Browse files
committed
fix issue 62
Signed-off-by: Ceki Gulcu <ceki@qos.ch>
1 parent db444fa commit 7d73278

File tree

6 files changed

+171
-18
lines changed

6 files changed

+171
-18
lines changed

src/main/java/org/apache/log4j/helpers/Loader.java

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import java.net.URL;
2121
import java.lang.reflect.Method;
2222
import java.lang.reflect.InvocationTargetException;
23-
import java.io.InterruptedIOException;
2423

2524
/**
2625
* Load resources (or images) from various sources.
@@ -56,7 +55,9 @@ public static URL getResource(String resource, Class clazz) {
5655
/**
5756
* This method will search for <code>resource</code> in different places. The search order is as follows:
5857
* <ol>
59-
*
58+
* <li><p>Search for <code>resource</code> using the thread context class loader,
59+
* unless "log4j.ignoreTCL" system property was set to true.</p>
60+
* </li>
6061
* <li><p>Search for <code>resource</code> using the class
6162
* loader that loaded this class (<code>Loader</code>).<p>
6263
* </li>
@@ -67,31 +68,35 @@ public static URL getResource(String resource, Class clazz) {
6768
*
6869
* <p>Nota bene: In versions of reload4j 1.2.23 and earlier, the jaadoc documentation stated that
6970
* the thread context class loader was used but when running under JDK 9 and later this
70-
* was <b>not</b> actually the case. As of version 1.2.24, the javadoc above matches the code as executed.
71+
* was <b>not</b> actually the case. As of version 1.2.25, the javadoc corresponds to the original
72+
* intention as documented.
7173
* </p>
7274
*
7375
*
7476
* @param resource the resource to load
7577
*/
7678
static public URL getResource(String resource) {
77-
ClassLoader classLoader = null;
78-
URL url = null;
7979

8080
try {
81-
// We could not find resource. Ler us now try with the
82-
// classloader that loaded this class.
83-
classLoader = Loader.class.getClassLoader();
84-
if (classLoader != null) {
85-
LogLog.debug("Trying to find [" + resource + "] using " + classLoader + " class loader.");
86-
url = classLoader.getResource(resource);
87-
if (url != null) {
88-
return url;
89-
}
81+
// unless intsructed to ignore the TCL, try getting the resource using TCL, return if found.
82+
if(!ignoreTCL) {
83+
URL url0 = innerGetResource(resource, getTCL());
84+
if(url0 != null) { return url0; }
9085
}
86+
87+
// if we were instructed to ignore TCL or if no url was dound, try using the
88+
// class loader that loaded this class.
89+
URL url = innerGetResource(resource, Loader.class.getClassLoader());
90+
if(url != null) { return url; }
91+
9192
} catch (SecurityException t) {
9293
// can't be InterruptedException or InterruptedIOException
9394
// since not declared, must be error or RuntimeError.
9495
LogLog.warn(TSTR, t);
96+
} catch (InvocationTargetException e) {
97+
throw new RuntimeException(e);
98+
} catch (IllegalAccessException e) {
99+
throw new RuntimeException(e);
95100
}
96101

97102
// Last ditch attempt: get the resource from the class path. It
@@ -102,6 +107,15 @@ static public URL getResource(String resource) {
102107
return ClassLoader.getSystemResource(resource);
103108
}
104109

110+
private static URL innerGetResource(String resource, ClassLoader classLoader) {
111+
if (classLoader != null) {
112+
LogLog.debug("Trying to find [" + resource + "] using " + classLoader + " class loader.");
113+
return classLoader.getResource(resource);
114+
} else {
115+
return null;
116+
}
117+
}
118+
105119
/**
106120
* Are we running under JDK 1.x?
107121
* @deprecated with no replacement

src/test/java/org/apache/log4j/testUtil/VersionUtil.java renamed to src/main/java/org/apache/log4j/helpers/VersionUtil.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
package org.apache.log4j.testUtil;
16+
package org.apache.log4j.helpers;
1717

1818
public class VersionUtil {
1919
static final int DEFAULT_GUESS = 8;

src/main/java/org/apache/log4j/spi/LoggingEvent.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -576,9 +576,9 @@ public Set getPropertyKeySet() {
576576
*/
577577
public Map getProperties() {
578578
getMDCCopy();
579-
Map properties;
579+
Map properties; // local variable
580580
if (mdcCopy == null) {
581-
properties = new HashMap();
581+
properties = new HashMap(); // local variable not otherwise used within the event
582582
} else {
583583
properties = mdcCopy;
584584
}

src/test/java/org/apache/log4j/MDCTestCase.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
import java.lang.ref.Reference;
2020
import java.lang.reflect.Field;
2121

22-
import org.apache.log4j.testUtil.VersionUtil;
22+
import org.apache.log4j.helpers.VersionUtil;
2323

2424
import junit.framework.TestCase;
2525

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package org.apache.log4j.helpers;
2+
3+
import org.junit.Test;
4+
5+
import static org.junit.Assert.assertEquals;
6+
7+
public class VersionUtilTest {
8+
9+
@Test
10+
public void smoke() {
11+
assertEquals(4, VersionUtil.getJavaMajorVersion("1.4.xx"));
12+
assertEquals(5, VersionUtil.getJavaMajorVersion("1.5"));
13+
assertEquals(5, VersionUtil.getJavaMajorVersion("1.5.xx"));
14+
assertEquals(5, VersionUtil.getJavaMajorVersion("1.5AA"));
15+
assertEquals(7, VersionUtil.getJavaMajorVersion("1.7.0_80-b15"));
16+
assertEquals(8, VersionUtil.getJavaMajorVersion("1.8.0_311"));
17+
assertEquals(9, VersionUtil.getJavaMajorVersion("9EA"));
18+
assertEquals(9, VersionUtil.getJavaMajorVersion("9.0.1"));
19+
assertEquals(18, VersionUtil.getJavaMajorVersion("18.3+xx"));
20+
assertEquals(19, VersionUtil.getJavaMajorVersion("19"));
21+
22+
}
23+
}
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
package org.apache.log4j.net;
2+
3+
4+
import org.junit.Before;
5+
import org.junit.Ignore;
6+
import org.junit.Test;
7+
8+
import java.io.ByteArrayInputStream;
9+
import java.io.ByteArrayOutputStream;
10+
import java.io.IOException;
11+
import java.io.ObjectInputStream;
12+
import java.io.ObjectOutputStream;
13+
import java.lang.reflect.Field;
14+
import java.util.HashMap;
15+
import java.util.Hashtable;
16+
17+
@Ignore
18+
public class HashmapDOSTest {
19+
20+
Hashtable<Object, Object> ht = new Hashtable<Object, Object>();
21+
ByteArrayOutputStream baos = new ByteArrayOutputStream();
22+
ObjectOutputStream oos;
23+
24+
ObjectInputStream ois;
25+
int maxHashMapCapacity = getMaxHashMapCapacityValue();
26+
27+
@Before
28+
public void beforeEach() throws IOException {
29+
oos = new ObjectOutputStream(baos);
30+
}
31+
@Test
32+
public void smokeHashMap() throws Exception {
33+
HashMap<Object, Object> ht = createDeepMap(null, 10);
34+
setSizeUsingReflection(ht, maxHashMapCapacity);
35+
oos.writeObject(ht);
36+
oos.flush();
37+
oos.close();
38+
39+
byte[] byteArray = baos.toByteArray();
40+
41+
System.out.println("byteArray,length="+byteArray.length);
42+
43+
44+
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
45+
ois = new ObjectInputStream(bais);
46+
47+
Object o = ois.readObject();
48+
49+
50+
}
51+
@Test
52+
public void smokeHashtable() throws Exception {
53+
Hashtable ht = new Hashtable();
54+
ht.put("1", "1");
55+
oos.writeObject(ht);
56+
oos.flush();
57+
oos.close();
58+
59+
byte[] byteArray = baos.toByteArray();
60+
61+
System.out.println("byteArray,length="+byteArray.length);
62+
63+
64+
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
65+
ois = new ObjectInputStream(bais);
66+
67+
Hashtable htback = (Hashtable) ois.readObject();
68+
69+
System.out.println(htback.get("1"));
70+
71+
}
72+
73+
private static void setSizeUsingReflection(HashMap map, int size) throws Exception {
74+
Field sizeField = HashMap.class.getDeclaredField("size");
75+
sizeField.setAccessible(true);
76+
77+
while (map != null) {
78+
sizeField.set(map, size);
79+
map = (HashMap) map.keySet().iterator().next();
80+
}
81+
}
82+
83+
static int getMaxHashMapCapacityValue() {
84+
Field maxHashMapCapacityField = null;
85+
try {
86+
maxHashMapCapacityField = HashMap.class.getDeclaredField("MAXIMUM_CAPACITY");
87+
maxHashMapCapacityField.setAccessible(true);
88+
89+
int maxHashMapCapacity = maxHashMapCapacityField.getInt(null);
90+
return maxHashMapCapacity;
91+
} catch (NoSuchFieldException e) {
92+
throw new RuntimeException("Unable to obtain field HashMap.MAXIMUM_CAPACITY", e);
93+
} catch (IllegalAccessException e) {
94+
throw new RuntimeException("Unable to read HashMap.MAXIMUM_CAPACITY", e);
95+
}
96+
}
97+
98+
99+
private static HashMap createDeepMap(HashMap child, int depth) {
100+
if (child == null) {
101+
child = new HashMap();
102+
// add one last element so that buffer is flushed
103+
child.put(null, null);
104+
}
105+
106+
if (depth <= 1) {
107+
return child;
108+
}
109+
110+
HashMap parent = new HashMap();
111+
parent.put(child, null);
112+
113+
return createDeepMap(parent, depth - 1);
114+
}
115+
116+
}

0 commit comments

Comments
 (0)