qase-tms / qase-java

Qase TMS Java SDK
https://developers.qase.io
Apache License 2.0
17 stars 5 forks source link

NoSuchMethodError when calling RunsApi.createRun() #34

Closed franke0739 closed 2 years ago

franke0739 commented 2 years ago

Sample:

qaseApi = Configuration.getDefaultApiClient();
qaseApi.setApiKey(apiToken);

runsApi = new RunsApi(qaseApi);

runsApi.createRun(this.projectCode, new RunCreate().title("Automation Test Example").cases(Arrays.asList(22L, 25L)));

Error: java.lang.NoSuchMethodError: okhttp3.RequestBody.create(Ljava/lang/String;Lokhttp3/MediaType;)Lokhttp3/RequestBody; at io.qase.client.ApiClient.serialize(ApiClient.java:831) at io.qase.client.ApiClient.buildRequest(ApiClient.java:1085) at io.qase.client.ApiClient.buildCall(ApiClient.java:1034) at io.qase.client.api.RunsApi.createRunCall(RunsApi.java:210) at io.qase.client.api.RunsApi.createRunValidateBeforeCall(RunsApi.java:227) at io.qase.client.api.RunsApi.createRunWithHttpInfo(RunsApi.java:264) at io.qase.client.api.RunsApi.createRun(RunsApi.java:246)

savkk commented 2 years ago

Could you check OkHttp in the transitive dependencies of the project?

franke0739 commented 2 years ago

I am using okhttp-3.10.0 and the method parameter of create is MediaType, String:

okhttp-3.10.0

public static RequestBody create(@Nullable MediaType contentType, String content) {
        Charset charset = Util.UTF_8;
        if (contentType != null) {
            charset = contentType.charset();
            if (charset == null) {
                charset = Util.UTF_8;
                contentType = MediaType.parse(contentType + "; charset=utf-8");
            }
        }

        byte[] bytes = content.getBytes(charset);
        return create(contentType, bytes);
    }

But the sequence of parameter in ApiClient.class is Object, MediaType

public RequestBody serialize(Object obj, String contentType) throws QaseException {
        if (obj instanceof byte[]) {
            return RequestBody.create((byte[])obj, MediaType.parse(contentType));
        } else if (obj instanceof File) {
            return RequestBody.create((File)obj, MediaType.parse(contentType));
        } else if (this.isJsonMime(contentType)) {
            String content;
            if (obj != null) {
                content = this.json.serialize(obj);
            } else {
                content = null;
            }

            return RequestBody.create(content, MediaType.parse(contentType));
        } else {
            throw new QaseException("Content type \"" + contentType + "\" is not supported");
        }
    }
savkk commented 2 years ago

Can you update okhttp to the major version 4? Qase API client works only with okhttp 4

franke0739 commented 2 years ago

Updated to version 4.9.3 Getting different error.

java.lang.NoSuchFieldError: Companion
    at okhttp3.internal.Util.<clinit>(Util.kt:70)
    at okhttp3.internal.concurrent.TaskRunner.<clinit>(TaskRunner.kt:309)
    at okhttp3.ConnectionPool.<init>(ConnectionPool.kt:41)
    at okhttp3.ConnectionPool.<init>(ConnectionPool.kt:47)
    at okhttp3.OkHttpClient$Builder.<init>(OkHttpClient.kt:471)
    at io.qase.client.ApiClient.initHttpClient(ApiClient.java:109)
    at io.qase.client.ApiClient.initHttpClient(ApiClient.java:105)
    at io.qase.client.ApiClient.<init>(ApiClient.java:84)
    at io.qase.client.Configuration.<clinit>(Configuration.java:18)
savkk commented 2 years ago

Looks like still a transitive dependency error. Could you check where the okhttp dependency is coming from?

franke0739 commented 2 years ago

The okhttp is coming from maven.

savkk commented 2 years ago

I meant from what dependency okhttp is coming from?

franke0739 commented 2 years ago

The okhttp is coming from qase-java pom.xml below: https://github.com/qase-tms/qase-java/blob/27e4b133762fb8b6ae1a1c106593d771aa084b63/qase-api/pom.xml#L47

<groupId>com.squareup.okhttp3</groupId>
 <artifactId>logging-interceptor</artifactId>
 <version>4.9.2</version>

I believe logging-interceptor 4.9.2 is depend on okhttp 3.10.0 image

https://github.com/qase-tms/qase-java/blob/27e4b133762fb8b6ae1a1c106593d771aa084b63/qase-api/src/main/java/io/qase/client/ApiClient.java#L821 Line above from qase-api/ApiClient.java will call okhttp RequestBody.create(), then error java.lang.NoSuchMethodError. I suspect the order of parameters caused the error NoSuchMethodError when calling create(), please help to investigate, thanks.

return RequestBody.create((byte[]) obj, MediaType.parse(contentType)); return RequestBody.create(MediaType.parse(contentType), (byte[]) obj);

savkk commented 2 years ago

This error happens because one of dependences from your project has okhttp 3.10.0 transitive dependency. logging-interceptor 4.9.2 is depends on the same version okhttp - 4.9.2. You can see this in its pom.xml. You can try to use maven dependency tree for looking for dependency that is using okhttp:3.10.0 and exclude it. If you are using intellij idea it can help you https://www.jetbrains.com/help/idea/work-with-maven-dependencies.html#maven_dependency_diagram

franke0739 commented 2 years ago

Thanks @savkk , this advice is very helpful, i had exclude all the okhttp & okio (I have to exclude this as well) from the dependencies (selenium-java 3.14.0 & slack-api-client 1.20.1).

Now this issue is fixed. Once again appreciated your patience on this.