square / square-java-sdk

Java client library for the Square API

Home Page:https://developer.squareup.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

com.squareup.square.api.DefaultCheckoutApi.createPaymentLink fails with java.lang.NoSuchMethodError

zeppelinux opened this issue · comments

When I'm trying to use the com.squareup.square.api.DefaultCheckoutApi.createPaymentLink it fails:
java.lang.NoSuchMethodError: 'okhttp3.RequestBody okhttp3.RequestBody.create(byte[], okhttp3.MediaType)'

at io.apimatic.okhttpclient.adapter.OkClient.convertRequest(OkClient.java:420)
at io.apimatic.okhttpclient.adapter.OkClient.execute(OkClient.java:258)
at io.apimatic.core.ApiCall.execute(ApiCall.java:65)
at com.squareup.square.api.DefaultCheckoutApi.createPaymentLink(DefaultCheckoutApi.java:203)
at com.diligesoft.collarclub.backend.beans.SquareBean.test(SquareBean.java:59)

Expected behavior
Should not fail

To Reproduce
Steps to reproduce the bug:

  1. Use version 28.0.0.20230419
  2. Try to invoke the DefaultCheckoutApi.createPaymentLink

Screenshots
If applicable, add screenshots to help explain the bug.

Square SDK version
For example: 28.0.0.20230419

hi @zeppelinux

Can you provide any more information about how you are using this? Such as providing some code showing your call to the createPaymentLink?

Can you confirm if you can use the SDK to properly query any of our other endpoints? Such as List locations?

@zenmasterjobo some endpoints are working, for ex:

CatalogApi api = client.getCatalogApi();
ListCatalogResponse resp = api.listCatalog(null, "ITEM", null);

CheckoutApi checkoutApi = client.getCheckoutApi();
ListPaymentLinksResponse lpsresp = checkoutApi.listPaymentLinks(null, null);

I fixed the issue (at least all the calls I'm using so far are working) by bumping your okhttp version to 5.0.0-alpha.11 (tried with 3.x.x and 4.x.x - didn't work).

@zeppelinux

Can you share any of your code that is invoking the Default Checkout API? I am successfully creating a checkout link using CheckoutApi. Can you help me understand why you are using the DefaultCheckoutApi instead of the CheckoutApi?

package com.square.examples;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.concurrent.ExecutionException;

import com.squareup.square.*;
import com.squareup.square.api.*;
import com.squareup.square.models.*;

public class Quickstart {
    public static void main(String[] args) {

        InputStream inputStream =
            Quickstart.class.getResourceAsStream("/config.properties");
        Properties prop = new Properties();

        try {
            prop.load(inputStream);
        } catch (IOException e) {
            System.out.println("Error reading properties file");
            e.printStackTrace();
        }

        SquareClient client = new SquareClient.Builder()
            .accessToken(prop.getProperty("SQUARE_ACCESS_TOKEN"))
            .environment(Environment.SANDBOX)
            .build();

        CheckoutApi checkoutApi = client.getCheckoutApi();

        Money priceMoney = new Money.Builder()
        .amount(100L)
        .currency("USD")
        .build();

        QuickPay quickPay = new QuickPay.Builder(
            "Test Order",
            priceMoney,
            "LOCATION ID")
        .build();

        CreatePaymentLinkRequest body = new CreatePaymentLinkRequest.Builder()
        .quickPay(quickPay)
        .build();

        try {
            CreatePaymentLinkResponse paymentLink = checkoutApi.createPaymentLinkAsync(body).get();
            System.out.println("Success!");
            System.out.println(paymentLink);
        } catch (InterruptedException | ExecutionException e) {
            System.out.println("Failed to make the request");
            System.out.println(String.format("Exception: %s", e.getMessage()));
        }

        SquareClient.shutdown();
    }
}

@zenmasterjobo here is the code:

@PostConstruct
 public void init(){
        client = new SquareClient.Builder()
                .accessToken(accessToken)
                .environment(Environment.SANDBOX)
                .build();
    }

public void test() throws IOException, ApiException {

        List<CatalogItem> catalogItems = new ArrayList<>();
        CatalogApi api = client.getCatalogApi();
        ListCatalogResponse resp = api.listCatalog(null, "ITEM", null);
        for (CatalogObject obj : resp.getObjects()) {
            CatalogItem item = obj.getItemData();
            log.info("item {}", item);
            catalogItems.add(item);
        }

        CheckoutApi checkoutApi = client.getCheckoutApi();
        ListPaymentLinksResponse lpsresp = checkoutApi.listPaymentLinks(null, null);

        CreatePaymentLinkRequest body = new CreatePaymentLinkRequest.Builder()
                //.idempotencyKey("cd9e25dc-d9f2-4430-aedb-61605070e95f")
                .checkoutOptions(new CheckoutOptions.Builder()
                        .acceptedPaymentMethods(new AcceptedPaymentMethods.Builder().applePay(true).googlePay(true).build()).build())
                .prePopulatedData(new PrePopulatedData.Builder().buyerEmail("vasily@pupkin.com")
                        .buyerAddress(new Address.Builder().country("CA").firstName("Vasily").lastName("Pupkin").postalCode("V9Y L6T")
                                .locality("Somewhere").addressLine1("4678 Some Street.").build()).build())
                .quickPay(new QuickPay.Builder(
                        catalogItems.get(0).getName(),
                        new Money.Builder()
                             .amount(catalogItems.get(0).getVariations().get(0).getItemVariationData().getPriceMoney().getAmount())
                                .currency("CAD")
                                .build(),
                        "LVA3770KXBP3P"
                ).build()).build();

        try {
            CreatePaymentLinkResponse presp = checkoutApi.createPaymentLink(body);  //fails here
            presp.getErrors();
        } catch (Exception ex) {
            ex.getMessage();
        }
 }

The default version of com.squareup.okhttp configured in current Square Java SDK pom is 3.14.9 The RequestBody class compiled in 3.14.9 doesn't have create(byte[], okhttp3.MediaType), only create(@nullable MediaType contentType, byte[] content) is present. The problem is that io.apimatic.okhttpclient.adapter.OkClient.convertRequest() calls method with the wrong signature (fails with createPaymentLinkAsync() as well):

java.lang.NoSuchMethodError: 'okhttp3.RequestBody okhttp3.RequestBody.create(byte[], okhttp3.MediaType)'

	at io.apimatic.okhttpclient.adapter.OkClient.convertRequest(OkClient.java:420)
	at io.apimatic.okhttpclient.adapter.OkClient.executeAsync(OkClient.java:224)
	at io.apimatic.core.ApiCall.lambda$executeAsync$1(ApiCall.java:75)
	at io.apimatic.core.request.async.AsyncExecutor.makeHttpCallAsync(AsyncExecutor.java:38)
	at io.apimatic.core.ApiCall.executeAsync(ApiCall.java:74)
	at com.squareup.square.api.DefaultCheckoutApi.createPaymentLinkAsync(DefaultCheckoutApi.java:216)
	at com.diligesoft.collarclub.backend.beans.SquareBean.test(SquareBean.java:107)
	at com.diligesoft.collarclub.backend.beans.SquareBean_ClientProxy.test(Unknown Source)
	at com.diligesoft.collarclub.backend.beans.SquareBeanTest.test1(SquareBeanTest.java:20)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at io.quarkus.test.junit.QuarkusTestExtension.runExtensionMethod(QuarkusTestExtension.java:999)
	at io.quarkus.test.junit.QuarkusTestExtension.interceptTestMethod(QuarkusTestExtension.java:813)
	at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(InterceptingExecutableInvoker.java:103)
	at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.lambda$invoke$0(InterceptingExecutableInvoker.java:93)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
	at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:156)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:147)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:86)
	at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(InterceptingExecutableInvoker.java:103)
	at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.lambda$invoke$0(InterceptingExecutableInvoker.java:93)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
	at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:92)
	at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:86)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:217)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:213)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:138)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:147)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:127)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:90)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:55)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:102)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:54)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
	at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
	at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)
	at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:57)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
	at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
	at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:232)
	at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:55)

@zeppelinux

Thanks for sending over the code! Unfortunately, I am unable to reproduce your error and am successfully creating a Checkout link using your supplied code (other than updating it to use one of my location IDs and changing the currency to USD).

The default version of com.squareup.okhttp configured in current Square Java SDK pom is 3.14.9

I'm not seeing okhttp listed here, only the apimatic adapter https://github.com/square/square-java-sdk/blob/master/pom.xml

Anything else you can share about your build environment that shed some light on why we are getting different results?

Have you confirmed that your request is working if you call the API directly with postman or using our API Explorer?

@zenmasterjobo As I said, the request is working if I change the version of okhttp to 5.0.0-alpha.11 in my pom (and excluding it from square pom)

You can find the reproducer here https://github.com/zeppelinux/square-okhttp-problem

  1. check out the project
  2. set SQUARE_ACCESSTOKEN env variable (or create /.env file and set it there)
  3. ./mvnw clean compile test

Here is my ./mvnw -version output:

Apache Maven 3.8.8 (4c87b05d9aedce574290d1acc98575ed5eb6cd39)
Maven home: /Users/me/.m2/wrapper/dists/apache-maven-3.8.8-bin/67c30f74/apache-maven-3.8.8
Java version: 17.0.2, vendor: Oracle Corporation, runtime: /Users/dimas/Library/Java/JavaVirtualMachines/openjdk-17.0.2/Contents/Home
Default locale: en_CA, platform encoding: UTF-8
OS name: "mac os x", version: "13.3.1", arch: "x86_64", family: "mac"

Intellij IDEA Dependency Analyser shows problem as well:
Screenshot 2023-05-01 at 5 55 42 PM 1

hey @zeppelinux

Thanks for supplying the repo, I cloned it and am reproducing your same error.

After spending a few hours this morning stepping through your code, I can't find anything that is inherently wrong with the Square Java SDK. Unfortunately I can't help any further as my own Java experience is pretty limited.

I have gone ahead and created a simple repo here: https://github.com/zenmasterjobo/square-java-sdk-quickstart which demonstrates the createPaymentLink with your code executing just fine. Perhaps your expertise may be able to compare this repo to your own and discern what about your environment is causing the error with the http request. Could be one of your other project dependencies like Quarkus might be messing with the okhttp dependency.

Anyways, if you run into other issues related to Square please let me know.