You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@santuario.apache.org by gi...@apache.org on 2015/02/03 20:22:18 UTC
svn commit: r1656896 - in /santuario/xml-security-java/trunk/src:
main/java/org/apache/xml/security/utils/
test/java/org/apache/xml/security/test/dom/utils/
Author: giger
Date: Tue Feb 3 19:22:18 2015
New Revision: 1656896
URL: http://svn.apache.org/r1656896
Log:
- try to make DocumentBuilderPooling tests more reliable and additionally some small impl. fixes
Added:
santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/dom/utils/DocumentBuilderPoolingTest.java
- copied, changed from r1656879, santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/dom/utils/PoolingTest.java
Removed:
santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/dom/utils/PoolingTest.java
Modified:
santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/utils/WeakObjectPool.java
santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/utils/XMLUtils.java
Modified: santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/utils/WeakObjectPool.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/utils/WeakObjectPool.java?rev=1656896&r1=1656895&r2=1656896&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/utils/WeakObjectPool.java (original)
+++ santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/utils/WeakObjectPool.java Tue Feb 3 19:22:18 2015
@@ -27,7 +27,7 @@ import java.util.concurrent.LinkedBlocki
/**
* Abstract base class for pooling objects. The two public methods are
- * {@link #getObject()} and ({@link #repool()}. Objects are held through
+ * {@link #getObject()} and ({@link #repool(Object)}. Objects are held through
* weak references so even objects that are not repooled are subject to garbage collection.
*
* Subclasses must implement the abstract {@link #createObject()}.
@@ -40,6 +40,16 @@ public abstract class WeakObjectPool<T,
private static final Integer MARKER_VALUE = Integer.MAX_VALUE;//once here rather than auto-box it?
+ /** created, available objects to be checked out to clients */
+ private final BlockingQueue<WeakReference<T>> available;
+
+ /**
+ * Synchronized, identity map of loaned out objects (WeakHashMap);
+ * use to ensure we repool only object originating from here
+ * and do it once.
+ */
+ private final Map<T, Integer> onLoan;
+
/**
* The lone constructor.
*/
@@ -76,7 +86,6 @@ public abstract class WeakObjectPool<T,
if (retValue == null) {
//empty pool; create & add new one
retValue = createObject();
- ref = new WeakReference<T>(retValue);
}
onLoan.put(retValue, MARKER_VALUE);
return retValue;
@@ -102,14 +111,4 @@ public abstract class WeakObjectPool<T,
}
return false;
}
-
- /** created, available objects to be checked out to clients */
- private final BlockingQueue<WeakReference<T>> available;
-
- /**
- * Synchronized, identity map of loaned out objects (WeakHashMap);
- * use to ensure we repool only object originating from here
- * and do it once.
- */
- private final Map<T, Integer> onLoan;
}
Modified: santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/utils/XMLUtils.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/utils/XMLUtils.java?rev=1656896&r1=1656895&r2=1656896&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/utils/XMLUtils.java (original)
+++ santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/utils/XMLUtils.java Tue Feb 3 19:22:18 2015
@@ -1074,8 +1074,7 @@ public final class XMLUtils {
/**
* Return this document builder to be reused
* @param db DocumentBuilder returned from any of {@link #createDocumentBuilder} methods.
- * @param disAllowDocTypeDeclarations We can't figure out its value from the documentBuilder itself
- * @return whether it was successfully returned to the pool
+ * @return whether it was successfully returned to the pool
*/
public static boolean repoolDocumentBuilder(DocumentBuilder db) {
if (db == null || !(db instanceof DocumentBuilderProxy)) {
@@ -1107,10 +1106,6 @@ public final class XMLUtils {
return disAllowDocTypeDeclarations;
}
- public int hashCode() {
- return delegate.hashCode();
- }
-
public void reset() {
delegate.reset();
}
@@ -1119,10 +1114,6 @@ public final class XMLUtils {
return delegate.parse(is);
}
- public boolean equals(Object obj) {
- return delegate.equals(obj);
- }
-
public Document parse(InputStream is, String systemId)
throws SAXException, IOException {
return delegate.parse(is, systemId);
@@ -1136,10 +1127,6 @@ public final class XMLUtils {
return delegate.parse(f);
}
- public String toString() {
- return delegate.toString();
- }
-
public Schema getSchema() {
return delegate.getSchema();
}
Copied: santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/dom/utils/DocumentBuilderPoolingTest.java (from r1656879, santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/dom/utils/PoolingTest.java)
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/dom/utils/DocumentBuilderPoolingTest.java?p2=santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/dom/utils/DocumentBuilderPoolingTest.java&p1=santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/dom/utils/PoolingTest.java&r1=1656879&r2=1656896&rev=1656896&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/dom/utils/PoolingTest.java (original)
+++ santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/dom/utils/DocumentBuilderPoolingTest.java Tue Feb 3 19:22:18 2015
@@ -18,125 +18,152 @@
*/
package org.apache.xml.security.test.dom.utils;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNotSame;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.util.Random;
-import java.util.concurrent.CancellationException;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
+import org.apache.xml.security.utils.WeakObjectPool;
+import org.apache.xml.security.utils.XMLUtils;
+import org.junit.Test;
import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.ParserConfigurationException;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Field;
+import java.util.Iterator;
+import java.util.concurrent.*;
-import org.apache.xml.security.utils.XMLUtils;
-import org.junit.Test;
+import static org.junit.Assert.*;
+
+public class DocumentBuilderPoolingTest {
+
+ private static final String DOCUMENTBUILDERPROXY_CLASSNAME =
+ "org.apache.xml.security.utils.XMLUtils$DocumentBuilderProxy";
+
+ @Test
+ public void testEquals() throws Exception {
+ DocumentBuilder documentBuilder = XMLUtils.createDocumentBuilder(true);
+ assertEquals(documentBuilder, documentBuilder);
+ assertSame(documentBuilder, documentBuilder);
+ }
+
+ @Test
+ public void testGetValidatingDocumentBuilder() throws Exception {
+ DocumentBuilder documentBuilder = XMLUtils.createDocumentBuilder(true);
+ assertTrue(documentBuilder.isValidating());
+ }
+
+ @Test
+ public void testGetNonValidatingDocumentBuilder() throws Exception {
+ DocumentBuilder documentBuilder = XMLUtils.createDocumentBuilder(false);
+ assertFalse(documentBuilder.isValidating());
+ }
+
+ @Test
+ public void testGetValidatingAndAllowDocTypeDeclarationsDocumentBuilder() throws Exception {
+ DocumentBuilder documentBuilder = XMLUtils.createDocumentBuilder(true, false);
+ assertTrue(documentBuilder.isValidating());
+ assertEquals(documentBuilder.getClass().getName(), DOCUMENTBUILDERPROXY_CLASSNAME);
+ assertAllowDocTypeDeclarations(documentBuilder, false);
+ }
-public class PoolingTest {
-
@Test
- public void testPooling() throws ParserConfigurationException, InterruptedException, ExecutionException {
- //assert parameters
- DocumentBuilder db = XMLUtils.createDocumentBuilder(true);
- assertTrue(db.isValidating());
- DocumentBuilder db2 = XMLUtils.createDocumentBuilder(false);
- assertFalse(db2.isValidating());
- assertNotEquals(db2, db);
- DocumentBuilder db3 = XMLUtils.createDocumentBuilder(true, false);
- assertTrue(db3.isValidating());
- DocumentBuilder db4 = XMLUtils.createDocumentBuilder(false, false);
- assertFalse(db4.isValidating());
-
- //assert get
- DocumentBuilder db_ = XMLUtils.createDocumentBuilder(true);
- assertNotSame("db wasn't returned", db, db_);
- DocumentBuilder db2_ = XMLUtils.createDocumentBuilder(false);
- assertNotSame(db2, db2_);
- DocumentBuilder db3_ = XMLUtils.createDocumentBuilder(true, false);
- assertNotSame(db3, db3_);
- DocumentBuilder db4_ = XMLUtils.createDocumentBuilder(false, false);
- assertNotSame(db4, db4_);
-
- //assert get after return
- assertTrue(XMLUtils.repoolDocumentBuilder(db_));
- assertFalse("can't repool the same object twice!", XMLUtils.repoolDocumentBuilder(db_));
- DocumentBuilder db_1 = XMLUtils.createDocumentBuilder(true);
- assertSame(db_, db_1);
-
- assertTrue(XMLUtils.repoolDocumentBuilder(db2_));
- assertFalse("can't repool the same object twice!", XMLUtils.repoolDocumentBuilder(db2_));
- DocumentBuilder db_2 = XMLUtils.createDocumentBuilder(false);
- assertSame(db2_, db_2);
-
- assertTrue(XMLUtils.repoolDocumentBuilder(db3_));
- assertFalse("can't repool the same object twice!", XMLUtils.repoolDocumentBuilder(db3_));
- DocumentBuilder db_3 = XMLUtils.createDocumentBuilder(true, false);
- assertSame(db3_, db_3);
-
- assertTrue(XMLUtils.repoolDocumentBuilder(db4_));
- assertFalse("can't repool the same object twice!", XMLUtils.repoolDocumentBuilder(db4_));
- DocumentBuilder db_4 = XMLUtils.createDocumentBuilder(false, false);
- assertSame(db4_, db_4);
-
-// final byte[] largeArrays[] = new byte[1024][];
-// final DocumentBuilder[] dbLargeArrays = new DocumentBuilder[largeArrays.length];
+ public void testGetValidatingAndDisAllowDocTypeDeclarationsDocumentBuilder() throws Exception {
+ DocumentBuilder documentBuilder = XMLUtils.createDocumentBuilder(true, true);
+ assertTrue(documentBuilder.isValidating());
+ assertEquals(documentBuilder.getClass().getName(), DOCUMENTBUILDERPROXY_CLASSNAME);
+ assertAllowDocTypeDeclarations(documentBuilder, true);
+ }
+
+ private void assertAllowDocTypeDeclarations(DocumentBuilder documentBuilder, boolean allow) throws Exception {
+ Field field = documentBuilder.getClass().getDeclaredField("disAllowDocTypeDeclarations");
+ field.setAccessible(true);
+ assertEquals(allow, field.get(documentBuilder));
+ }
- int nThreads = Runtime.getRuntime().availableProcessors();
+ @Test
+ public void testNewDocumentBuilderInstances() throws Exception {
+ int count = 4;
+
+ // get all possible combinations of DocumentBuilders:
+ DocumentBuilder[] documentBuilders = new DocumentBuilder[count];
+ for (int i = 0; i < count; i++) {
+ documentBuilders[i] = XMLUtils.createDocumentBuilder(i / 2 > 0, i % 2 == 1);
+ }
+
+ //test that we got always a new instance:
+ for (int i = 0; i < count; i++) {
+ for (int j = i + 1; j < count; j++) {
+ assertNotEquals(documentBuilders[i], documentBuilders[j]);
+ assertNotSame(documentBuilders[i], documentBuilders[j]);
+ }
+ }
+ }
+
+ @Test
+ public void testRepoolingTwice() throws Exception {
+ DocumentBuilder documentBuilder = XMLUtils.createDocumentBuilder(true);
+ assertTrue(XMLUtils.repoolDocumentBuilder(documentBuilder));
+ assertFalse("can't repool the same object twice!", XMLUtils.repoolDocumentBuilder(documentBuilder));
+ }
+
+ @Test(timeout = 30000)
+ public void testPooling() throws Exception {
+ int nThreads = 8;
ExecutorService exec = Executors.newFixedThreadPool(nThreads);
- Future<?>[] results = new Future[nThreads];
- for(int i = 0; i < nThreads-1; i++) {
+ Future<?>[] results = new Future[nThreads];
+ for (int i = 0; i < nThreads - 1; i++) {
results[i] = exec.submit(new Runnable() {
@Override
public void run() {
- for(;;) {
- DocumentBuilder dbA[] = new DocumentBuilder[10];
- for (int i = 0; i < dbA.length; i++) {
- try {
- dbA[i] = XMLUtils.createDocumentBuilder(false);
- assertNotNull(dbA[i]);
- } catch (ParserConfigurationException e) {
- e.printStackTrace();
- fail(e.toString());
+ try {
+ while (true) {
+ // retrieve some DocumentBuilders...
+ DocumentBuilder documentBuilders[] = new DocumentBuilder[10];
+ for (int i = 0; i < documentBuilders.length; i++) {
+ documentBuilders[i] = XMLUtils.createDocumentBuilder(false);
+ assertNotNull(documentBuilders[i]);
+ }
+ // ...then repool them so that another thread may pickup them again
+ for (int i = 0; i < documentBuilders.length; i++) {
+ assertTrue(XMLUtils.repoolDocumentBuilder(documentBuilders[i]));
}
- assertNotNull(dbA[i]);
- }
- for(int i = 0; i < new Random().nextInt(dbA.length); i++) {
- assertTrue(XMLUtils.repoolDocumentBuilder(dbA[i]));
}
+ } catch (Exception e) {
+ throw new RuntimeException(e);
}
}
});
}
- results[nThreads-1] = exec.submit(new Runnable() {
+ // more or less mimic gc
+ results[nThreads - 1] = exec.submit(new Runnable() {
@Override
public void run() {
- for(;;) {
- byte[] largeArrays[] = new byte[1024][];
- for (int i = 0; i < largeArrays.length; i++)
- try {
- largeArrays[i] = new byte[1024*1024];
- } catch (OutOfMemoryError e) {
- System.out.println("OOM from largeArray");
- break;
+ try {
+ final Field poolField = XMLUtils.class.getDeclaredField("pools");
+ poolField.setAccessible(true);
+ final WeakObjectPool[] weakObjectPools = (WeakObjectPool[]) poolField.get(null);
+
+ final Field availableField = WeakObjectPool.class.getDeclaredField("available");
+ availableField.setAccessible(true);
+
+ while (true) {
+ final BlockingDeque blockingDeque = (BlockingDeque) availableField.get(weakObjectPools[1]);
+ Iterator iterator = blockingDeque.iterator();
+ while (iterator.hasNext()) {
+ ((WeakReference) iterator.next()).clear();
}
+ Thread.sleep(200);
+ }
+ } catch (InterruptedException e) {
+ return;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
}
}
});
+
exec.shutdown();
exec.awaitTermination(5, TimeUnit.SECONDS);
- for(Future<?> f : results) {
- if (!f.isDone())
+ for (Future<?> f : results) {
+ if (!f.isDone()) {
f.cancel(false);
+ }
try {
assertNull(f.get(1000, TimeUnit.MILLISECONDS));
} catch (CancellationException ce) {