Commit 0d83ed88 authored by Piotr Gawron's avatar Piotr Gawron
Browse files

jaxb deserializer is not thread safe

parent f09cf4ad
Pipeline #52724 passed with stage
in 26 minutes and 25 seconds
minerva (16.1.0~beta.1) stable; urgency=medium
* Bug fix: problem with serializing reaction kinetic function (#1636)
* Bug fix: reaction middle was not highlighted (#1637)
* Bug fix: when accessing data from cache in parallel, sometimes unexpected
exception was thrown (#1638)
-- Piotr Gawron <piotr.gawron@uni.lu> Fri, 18 Feb 2022 11:00:00 +0200
......
......@@ -77,7 +77,9 @@ public class XmlSerializer<T> {
}
StringWriter sw = new StringWriter();
try {
jaxbMarshaller.marshal(object, sw);
synchronized (jaxbMarshaller) {
jaxbMarshaller.marshal(object, sw);
}
} catch (final JAXBException e) {
throw new SerializationException(e);
} catch (final Exception e) {
......@@ -100,8 +102,10 @@ public class XmlSerializer<T> {
return null;
}
try {
return (T) jaxbUnmarshaller.unmarshal(node);
} catch (final Exception e) { // the library can throw NPE sometimes...
synchronized (jaxbUnmarshaller) {
return (T) jaxbUnmarshaller.unmarshal(node);
}
} catch (final Exception e) {
logger.error(e, e);
return null;
}
......
......@@ -14,6 +14,7 @@ import org.junit.runners.Suite.SuiteClasses;
PermanentDatabaseLevelCacheWithoutTransactionTest.class,
SourceNotAvailableTest.class,
WebPageDownloaderTest.class,
XmlSerializerTest.class
})
public class AllCacheTests {
......
package lcsb.mapviewer.annotation.cache;
import static org.junit.Assert.assertFalse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.lang3.mutable.MutableBoolean;
import org.junit.Test;
import org.w3c.dom.Node;
import lcsb.mapviewer.annotation.data.MeSH;
import lcsb.mapviewer.common.tests.TestUtils;
public class XmlSerializerTest extends TestUtils {
@Test
public void test() throws Exception {
MeSH mesh = new MeSH("id", "name", null, Arrays.asList("x", "y", "z", null));
XmlSerializer<MeSH> serializer = new XmlSerializer<>(MeSH.class);
String string = serializer.objectToString(mesh);
Node node = getNodeFromXmlString(string);
MutableBoolean exceptionHappened = new MutableBoolean(false);
List<Thread> threads = new ArrayList<>();
for (int j = 0; j < 2; j++) {
Thread thread = new Thread() {
@Override
public void run() {
try {
for (int i = 0; i < 10000; i++) {
serializer.xmlToObject(node);
}
} catch (Throwable e) {
exceptionHappened.setTrue();
e.printStackTrace();
}
}
};
thread.start();
threads.add(thread);
}
for (Thread thread : threads) {
thread.join();
}
assertFalse(exceptionHappened.booleanValue());
}
}
......@@ -58,7 +58,7 @@ public class TestUtils {
protected static double EPSILON = Configuration.EPSILON;
private static final Logger logger = LogManager.getLogger();
protected final Logger logger = LogManager.getLogger();
private static final int BLOCK_SIZE = 65536;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment