XChange
XChange copied to clipboard
Kucoin unable to load ExchangeMetaData, prevents start up
I'm still digging through the code, but I think something with the new Instrument code broke Kucoin.
For Binance.us, I was seeing a 'warning' message on startup:
An exception occured while loading the metadata file from the file system.
This is just a warning and can be ignored, but it may lead to unexpected results, so it's better to address it
That error is from BaseExchange.java:148
When I saw this on startup with Binance, I ignored it was marked as a warning. But, it appears it's fatal - for at least Kucoin. What I think is happening is KucoinExchange.java:94
throws an exception because in the KucoinAdapters.adaptMetadata
method, the debugger gets an npe on line 133. That line basically tries to call getInstruments()
from a null ExchangeMetaData
object.
public static ExchangeMetaData adaptMetadata(
ExchangeMetaData exchangeMetaData,
List<CurrenciesResponse> currenciesResponse,
List<SymbolResponse> symbolsResponse,
TradeFeeResponse tradeFee)
throws IOException {
>> Map<Instrument, InstrumentMetaData> currencyPairs = exchangeMetaData.getInstruments();
Map<Currency, CurrencyMetaData> currencies = exchangeMetaData.getCurrencies();
Map<String, CurrencyMetaData> stringCurrencyMetaDataMap =
adaptCurrencyMetaData(currenciesResponse);
I haven't had a chance to look through the rest of the exchanges, but any others that follow this pattern are probably broken as well.
The culprit for all this appears to be the InstrumentDeserializer
. When it tries to deserialize the exchange json file in the jar, it throws this error:
Cannot find a (Map) Key deserializer for type [simple type, class org.knowm.xchange.instrument.Instrument]
When I switched over the deserialize annotation to
@JsonDeserialize(keyUsing = InstrumentMapDeserializer.class)
I now get the error
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of
`org.knowm.xchange.instrument.Instrument` (no Creators, like default constructor, exist):
abstract types either need to be mapped to concrete types, have custom deserializer, or
contain additional type information
Looking back through the history, CurrencyPair
was a concrete class where Instrument
is an abstract class and Jackson fails on that, even with the deserializer class. I would note too that all the xchange-core
tests pass with just the existing @JsonDeserialize(using = InstrumentDeserializer.class)
annotation, so I could see how this was seen as ok. The Kucoin tests don't specifically test loading in the json exchange metadata, so that might be something to add in the future.
I don't know enough of the ins and outs of Jackson to know what to do at this point but I'll keep digging and seeing if I can find a solution. Maybe @timmolter and @makarid might want to take a look?