IllegalArgumentException карта инициализации хроники
Вот кусок кода, который у меня есть
MyValue sampleValue = Values.newHeapInstance(MyValue.class);
// subsequently set the couple of floats and int i have defined in MyValue interface
ChronicleMap<MyKey, MyValue> cache = ChronicleMapBuilder.of(MyKey.class, MyValue.class)
.entries(100)
.averageValue(sampleValue)
.create();
Когда я делаю это, я получаю ошибку
java.lang.IllegalArgumentException: использование BytesMarshallable и типа значения интерфейса, не поддерживаемого в net.openhft.chronicle.map.ChronicleMapBuilder.averageValue(ChronicleMapBuilder.java:660)
Может ли кто-нибудь помочь мне понять, является ли этот шаблон использования неправильным?
Если я перехожу к созданию MyValue путем реализации конкретного класса, а затем создания нового для него, как показано ниже, это работает:
MyValue sampleValue = new MyValueImpl();
// subsequently set the couple of floats and int i have defined in MyValue interface
ChronicleMap<MyKey, MyValue> cache = ChronicleMapBuilder.of(MyKey.class, MyValue.class)
.entries(100)
.averageValue(sampleValue)
.create();
2 ответа
Причину этого исключения можно найти в источнике:
if (Serializable.class.isAssignableFrom(valueClass))
LOG.warn("BytesMarshallable " + valueClass + " will be serialized as Serializable as the value class is an interface");
else
throw new IllegalArgumentException("Using BytesMarshallable and an interface value type not supported");
}
Который просто вызывает метод isAssignableFrom класса Class, который проверяет:
Определяет, является ли класс или интерфейс, представленный этим объектом Class, тем же или является суперклассом или суперинтерфейсом класса или интерфейса, представленного указанным параметром Class. Возвращает истину, если так; в противном случае возвращается false. Если этот объект Class представляет примитивный тип, этот метод возвращает true, если указанный параметр Class является именно этим объектом Class; в противном случае возвращается false.
Так что это проверяет, если Serializable
Класс представлен valueClass
, Так что я понимаю, что ваш MyValue
не реализует Serializable
интерфейс.
И да, даже комментарий гласит:
Настраивает среднее количество байтов, взятых по сериализованной форме значений
Так что, если я не ошибаюсь, просто позвольте вашему классу значений реализовать Serializable
интерфейс, и вы должны быть в порядке. Довольно... запутанное сообщение об исключении, я бы сказал.
Использование Values.newHeapInstance()
предполагает, что MyValue
это так называемый интерфейс значения. Объекты с определенным значением интерфейса имеют постоянный размер в сериализованной форме. Интерфейсы значений специально поддерживаются ChronicleMap, поэтому вам вообще не нужно настраивать размер значений, как показано в этом примере из учебника:
ChronicleMap<LongValue, Order> orders = ChronicleMap
.of(LongValue.class, Order.class)
.name("orders-map")
.entries(1_000_000)
.create();
LongValue key = Values.newHeapInstance(LongValue.class);
key.setValue(id);
orders.put(key, order);
Обратите внимание, что нет averageValue()
ни звони, ни averageValueSize()
ни constantValueSizeBySample()
,
Представленное сообщение об ошибке действительно сбивает с толку, тем более что ChronicleMap уже знает, что класс значений является интерфейсом значений, и знает его размер. Не стесняйтесь открыть вопрос в https://github.com/OpenHFT/Chronicle-Map.