From d1218415ef1116780f0d516e42aa8d424399b926 Mon Sep 17 00:00:00 2001 From: leventov Date: Wed, 31 Dec 2014 03:33:19 +0700 Subject: [PATCH] HCOLL-266 optional xStream dependency --- pom.xml | 4 +- .../chronicle/map/ChronicleMapBuilder.java | 66 +++++++++++++++++-- 2 files changed, 62 insertions(+), 8 deletions(-) diff --git a/pom.xml b/pom.xml index b9678d723..40b7bbcd4 100644 --- a/pom.xml +++ b/pom.xml @@ -70,6 +70,7 @@ com.thoughtworks.xstream xstream 1.4.7 + true @@ -165,9 +166,8 @@ net.openhft.chronicle.hash.serialization.internal + net.openhft.xstreem net.openhft.xstreem.converters - net.openhft.chronicle.hash.serialization.internal - diff --git a/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java b/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java index d1a3ac3ae..00f9ea9cf 100755 --- a/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java +++ b/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java @@ -18,8 +18,6 @@ package net.openhft.chronicle.map; -import com.thoughtworks.xstream.XStream; -import com.thoughtworks.xstream.converters.reflection.SunLimitedUnsafeReflectionProvider; import net.openhft.chronicle.hash.*; import net.openhft.chronicle.hash.replication.*; import net.openhft.chronicle.hash.serialization.*; @@ -44,6 +42,8 @@ import org.slf4j.LoggerFactory; import java.io.*; import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.net.InetSocketAddress; import java.util.ArrayList; import java.util.HashMap; @@ -114,6 +114,9 @@ public final class ChronicleMapBuilder implements Cloneable, private static final double UNDEFINED_DOUBLE_CONFIG = Double.NaN; + private static final int XML_SERIALIZATION = 1; + private static final int BINARY_SERIALIZATION = 2; + private List jsonConverters = new ArrayList(); @@ -1327,9 +1330,22 @@ public final class ChronicleMapBuilder implements Cloneable, if (file.exists() && file.length() > 0) { try (FileInputStream fis = new FileInputStream(file); ObjectInputStream ois = new ObjectInputStream(fis)) { - XStream xStream = new XStream(new SunLimitedUnsafeReflectionProvider()); + Object m; + byte serialization = ois.readByte(); + if (serialization == XML_SERIALIZATION) { + m = deserializeHeaderViaXStream(ois); + } else if (serialization == BINARY_SERIALIZATION) { + try { + m = ois.readObject(); + } catch (ClassNotFoundException e) { + throw new AssertionError(e); + } + } else { + throw new IOException("Unknown map header serialization type: " + + serialization); + } VanillaChronicleMap map = - (VanillaChronicleMap) xStream.fromXML(ois); + (VanillaChronicleMap) m; map.headerSize = roundUpMapHeaderSize(fis.getChannel().position()); map.createMappedStoreAndSegments(file); // This is needed to property initialize key and value serialization builders, @@ -1357,8 +1373,10 @@ public final class ChronicleMapBuilder implements Cloneable, try (FileOutputStream fos = new FileOutputStream(file); ObjectOutputStream oos = new ObjectOutputStream(fos)) { - XStream xStream = new XStream(new SunLimitedUnsafeReflectionProvider()); - xStream.toXML(map, oos); + if (!trySerializeHeaderViaXStream(map, oos)) { + oos.writeByte(BINARY_SERIALIZATION); + oos.writeObject(map); + } oos.flush(); map.headerSize = roundUpMapHeaderSize(fos.getChannel().position()); map.createMappedStoreAndSegments(file); @@ -1367,6 +1385,42 @@ public final class ChronicleMapBuilder implements Cloneable, return establishReplication(map, singleHashReplication, channel); } + private static boolean trySerializeHeaderViaXStream( + VanillaChronicleMap map, ObjectOutputStream oos) throws IOException { + Class xStreamClass; + try { + xStreamClass = + Class.forName("net.openhft.xstreem.MapHeaderSerializationXStream"); + } catch (ClassNotFoundException e) { + xStreamClass = null; + } + if (xStreamClass == null) { + LOG.info("xStream not found, use binary ChronicleMap header serialization"); + return false; + } + try { + oos.writeByte(XML_SERIALIZATION); + Method toXML = xStreamClass.getMethod("toXML", Object.class, OutputStream.class); + toXML.invoke(xStreamClass.newInstance(), map, oos); + return true; + } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException | + InstantiationException e) { + throw new AssertionError(e); + } + } + + private static Object deserializeHeaderViaXStream(ObjectInputStream ois) { + try { + Class xStreamClass = + Class.forName("net.openhft.xstreem.MapHeaderSerializationXStream"); + Method fromXML = xStreamClass.getMethod("fromXML", InputStream.class); + return fromXML.invoke(xStreamClass.newInstance(), ois); + } catch (ClassNotFoundException | NoSuchMethodException | InvocationTargetException | + IllegalAccessException | InstantiationException e) { + throw new AssertionError(e); + } + } + ChronicleMap createWithoutFile( SingleChronicleHashReplication singleHashReplication, ReplicationChannel channel) { try {