IllegalArgumentException карта инициализации хроники - PullRequest
0 голосов
/ 07 января 2019

Вот кусок кода, который у меня есть

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 ]

0 голосов
/ 10 января 2019

Использование 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.

0 голосов
/ 07 января 2019

Причину этого исключения можно найти в источнике :

            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. Это возвращает true, если так; в противном случае возвращается false. Если этот объект класса представляет примитивный тип, этот метод возвращает true, если указанный Параметр Class является именно этим объектом Class; в противном случае возвращается ложь.

Таким образом, проверяется, представлен ли класс Serializable как valueClass. Поэтому я понимаю, что ваш MyValue не реализует интерфейс Serializable.

И да, даже комментарий гласит:

Конфигурирует среднее количество байтов, занятое сериализованной формой Значения

Так что, если я не ошибаюсь, просто позвольте вашему классу значений реализовать интерфейс Serializable, и все будет в порядке. Довольно ... запутанное сообщение об исключении, которое я бы сказал.

...