ktrader-tech / jxtp

XTP 的 Java 封装
Apache License 2.0
5 stars 5 forks source link

OnDepthMarketData : Method threw 'java.lang.NoSuchMethodError' exception. #3

Closed xiamubobby closed 3 years ago

xiamubobby commented 3 years ago
class Test {
    class S: QuoteSpi() {
        override fun OnQueryAllTickers(ticker_info: XTPQSI?, error_info: XTPRI?, is_last: Boolean) {
            super.OnQueryAllTickers(ticker_info, error_info, is_last)
            println(ticker_info)
        }
    }
    @Test
    fun testXTPLibraryLoaded() {
        val quoteApi = QuoteApi.CreateQuoteApi(1, "./log", XTP_LOG_LEVEL.XTP_LOG_LEVEL_INFO)
        quoteApi.RegisterSpi(S())    // <-----
        quoteApi.Login(<dummy>)
        quoteApi.QueryAllTickers(XTP_EXCHANGE_TYPE.XTP_EXCHANGE_SH).also(::println)
        quoteApi.Logout()
    }

}

Exception thrown on the tagged line: java.lang.NoSuchMethodError: OnDepthMarketData actually from: jxtpJNI.QuoteSpi_director_connect(this, this.swigCPtr, true, true) (QuoteSpi.class:288)

public QuoteSpi() {
    this(jxtpJNI.new_QuoteSpi(), true);
    jxtpJNI.QuoteSpi_director_connect(this, this.swigCPtr, true, true);
}
RationalityFrontline commented 3 years ago

This problem is caused by the wrong java method signature mapping in the generated jxtp.cpp file. Changing the code of line 2140 to the following content should solve the problem:

      "OnDepthMarketData", "(Lorg/rationalityfrontline/jxtp/XTPMD;[JI[JI)V", NULL

After the modification, you need to rerun ./cpp/build.sh and ./java/gradlew jar.

I tested login and release function with QuoteApi and TraderApi, they both work well. With QuoteApi, I can call QuoteApi.SubscribeMarketData, but currently the stock market is closed, so I don't know whether QuoteSpi.OnDepthMarketData can actually work. With TraderApi, I can confirm that TraderApi.QueryAsset and TraderSpi.OnQueryAsset can acutally work.

xiamubobby commented 3 years ago

This problem is caused by the wrong java method signature mapping in the generated jxtp.cpp file. Changing the code of line 2140 to the following content should solve the problem:

      "OnDepthMarketData", "(Lorg/rationalityfrontline/jxtp/XTPMD;[JI[JI)V", NULL

After the modification, you need to rerun ./cpp/build.sh and ./java/gradlew jar.

I tested login and release function with QuoteApi and TraderApi, they both work well. With QuoteApi, I can call QuoteApi.SubscribeMarketData, but currently the stock market is closed, so I don't know whether QuoteSpi.OnDepthMarketData can actually work. With TraderApi, I can confirm that TraderApi.QueryAsset and TraderSpi.OnQueryAsset can acutally work.

Many thanks. I will have it tested out tonight. BTW, regarding 2 things related:

  1. Mismatches like this
  2. Mandatory manual deletion towards specific lines in jxtp.cpp during the building procedure

I would like to confirm on if such things are all coming from the limitations of SWIG by nature? Or if it is something we can improve/eliminate by working on the building procedure a bit? If so then is there any brief descriptions on them? I am not quite familiar with SWIG, actually having just jumped into it due to this project. (Thanks for the awesome foundation works BTW :) ) So some brief clarification on that, of course only if you have the time for it, would be greatly welcomed.

I will continue to work with myself on getting familiar with your nicely picked tool chain, but acquiring knowledge directly from your side could always be more efficient, thus preferred. Again only if you have the time of course.

RationalityFrontline commented 3 years ago

Well, actually I am also not very familiar with SWIG :P

All these manual modifications are related with the OnDepthMarketData method. Theoretically there should be no more confusing things like this besides things related with the OnDepthMarketData method.

The origin of all the mess that come up with that method is due to my failure to deal with SWIG type transformation (long array). To solve the problem, you need to take a look into ./jxtp/swig/long_array.i.

I didn't use this library after creating it, so I just leave this problem unsolved. If I have spare time, I'll try to solve it.

xiamubobby commented 3 years ago

NoSuchMethodError jxtp-2.2.27.4-1.1.0.zip

had been gone from my side by this version of .jar file. Please release this towards 1.1.1 instead please.

RationalityFrontline commented 3 years ago

May be you could try this:

  1. Change the version in the ./java/build.gradle.kts to whatever you want, like "2.2.27.4-1.1.1" https://github.com/RationalityFrontline/jxtp/blob/2e4e18305266aa4e767c0efbd1ed7cf67d3bf90f/java/build.gradle.kts#L10
  2. In directory ./java, run command ./gradlew.sh publishToMavenLocal
  3. Then in your project using jxtp, add MavenLocal to your repositories:
    // in your build.gradle.kts file
    repositories {
    mavenLocal()
    mavenCentral()
    }
  4. Now you can use your new version of jxtp from your local maven repository.

I think this approach would be much faster and more convenient in development and testing. I will release a new version when everything relates with the OnDepthMarketData method are totally solved.

RationalityFrontline commented 3 years ago

In my test, I can recieve market data, but no depth data. Code:

class XtpQuoteSpi : QuoteSpi() {
    override fun OnDepthMarketData(market_data: XTPMD, bid1_qty: LongArray, max_bid1_count: Int, ask1_qty: LongArray, max_ask1_count: Int) {
        println("${market_data.data_time}, ${market_data.exchange_id}, ${market_data.ticker}, ${market_data.last_price}")
        println(bid1_qty.contentToString())
        println(ask1_qty.contentToString())
    }
}

Result:

20210423093937000, XTP_EXCHANGE_SZ, 300274, 75.77
[]
[]
20210423093944000, XTP_EXCHANGE_SZ, 300274, 76.03
[]
[]
xiamubobby commented 3 years ago

May be you could try this:

1. Change the version in the ./java/build.gradle.kts to whatever you want, like  "2.2.27.4-1.1.1"
   https://github.com/RationalityFrontline/jxtp/blob/2e4e18305266aa4e767c0efbd1ed7cf67d3bf90f/java/build.gradle.kts#L10

2. In directory ./java, run command `./gradlew.sh publishToMavenLocal`

3. Then in your project using jxtp, add MavenLocal to your repositories:
// in your build.gradle.kts file
repositories {
    mavenLocal()
    mavenCentral()
}
1. Now you can use your new version of jxtp from your local maven repository.

I think this approach would be much faster and more convenient in development and testing. I will release a new version when everything relates with the OnDepthMarketData method are totally solved.

No problem, many thanks on the clarification.