googleads / google-ads-java

Google Ads API Client Library for Java
Apache License 2.0
170 stars 176 forks source link

Calling AssetServiceClient.mutateAssets() hangs #398

Closed debedb closed 3 years ago

debedb commented 3 years ago

Calling AssetServiceClient.mutateAssets() hangs. Here's the call stack of the calling thread:

Unsafe.park(boolean, long) line: not available [native method]  
LockSupport.park(Object) line: 175  
AbstractApiFuture$InternalSettableFuture(AbstractFuture<V>).get() line: 472 
ExceptionTransformingUnaryCallable$ExceptionTransformingFuture(AbstractApiFuture<V>).get() line: 56 
Uninterruptibles.getUninterruptibly(Future<V>) line: 142    
Futures.getUnchecked(Future<V>) line: 1417  
ApiExceptions.callAndTranslateApiException(ApiFuture<ResponseT>) line: 53   
UnaryCallable$1(UnaryCallable<RequestT,ResponseT>).call(RequestT) line: 112 
AssetServiceClient.mutateAssets(MutateAssetsRequest) line: 212  
AssetServiceClient.mutateAssets(String, List<AssetOperation>) line: 201 

When trying to see what is happening in Charles, I see that on request to https://googleads.googleapis.com:443/google.ads.googleads.v6.services.AssetService/MutateAssets it says "Received response header. Waiting for response body…" and just the headers from the response:

:status 200
content-type    application/grpc
request-id  gManIovdpl6eCkY5PVAcEg
date    Mon, 08 Feb 2021 19:58:28 GMT
alt-svc h3-29=":443"; ma=2592000,h3-T051=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"

I create a new project, TestProject, to trying isolate the issue. Now the following program does return from the mutateAssets() call.

        Credentials creds = UserCredentials.newBuilder().setClientId( CLIENT_ID )
                .setClientSecret( CLIENT_SECRET ).setRefreshToken( REFRESH_TOKEN ).build();

        GoogleAdsClient client0 = GoogleAdsClient.newBuilder().setCredentials( creds ).setDeveloperToken( DEV_TOKEN ).build();
        GoogleAdsVersion googleClient = client0.getVersion6();
        AssetServiceClient assetClient = googleClient.createAssetServiceClient();
        Asset googleAsset = null;

        byte[] imageData = ByteStreams.toByteArray( new FileInputStream( new File( "./goose.jpg" ) ) );
        ImageAsset imageAsset = ImageAsset.newBuilder().setData( ByteString.copyFrom( imageData ) ).build();
        googleAsset = Asset.newBuilder().setName( "Bug" + System.currentTimeMillis() ).setType( AssetType.IMAGE )
                .setImageAsset( imageAsset ).build();
        List<AssetOperation> ops = new ArrayList<>();
        ops.add( AssetOperation.newBuilder().setCreate( googleAsset ).build() );
        System.out.println("Calling mutateAssets()");
        MutateAssetsResponse resp = assetClient.mutateAssets( CUSTOMER_ID, ops );
        System.out.println("Got result " + resp);
        for ( MutateAssetResult result : resp.getResultsList() )
        {
            System.out.println( result.getResourceName() );
        }

However, when turning Charles on with the TestProject, the same situation appears -- Charles says "Received response header. Waiting for response body…" and only the headers are seen:

:status 200
content-type    application/grpc
request-id  GR9EI5jXmksMAEdUZsPpPw
date    Mon, 08 Feb 2021 19:51:00 GMT
alt-svc h3-29=":443"; ma=2592000,h3-T051=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"

So it is possible that it is Charles interference when it is on that is causing just the header to go through, and is not the root cause.

I wonder if this is related to Deadlock depending on order of libraries in pom.xml. However, the workaround suggested in this issue is present in the pom.xml of both projects.

nwbirnie commented 3 years ago

I can see that the request IDs "GR9EI5jXmksMAEdUZsPpPw" and "gManIovdpl6eCkY5PVAcEg" reached our servers and were rejected for the same reason.

    error_code: "AuthorizationError.DEVELOPER_TOKEN_NOT_APPROVED",
    error_message: "The developer token is not approved. Non-approved developer tokens can only be used with test accounts."

However, that's not likely to be the cause of the issue you're seeing. It's more likely that you have another similar dependency issue to the deadlock, and the ClassNotFoundException (or whatever it is) isn't being propagated back to the calling thread.

Can you make sure that you have the correct version of dependencies being resolved in your project? Here are the correct versions for the latest version of the client library (10.1.0).

debedb commented 3 years ago

Yes, I do get that message in the TestProject -- I apologize for not including that, but that error is understandable and is not the issue. The issue is that the TestProject does run to get the error, whereas in another project (MainProject) I get a deadlock.

The relevant libraries included, in TestProject:

 <dependencies>

    <dependency>
      <groupId>com.google.api-ads</groupId>
      <artifactId>google-ads</artifactId>
      <version>10.1.0</version>
    </dependency>

     <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.7.25</version>
    </dependency> 

    <dependency>
      <groupId>com.google.api-ads</groupId>
      <artifactId>ads-lib</artifactId>
      <version>4.9.1</version>
    </dependency>

    <dependency>
      <groupId>com.google.api-ads</groupId>
      <artifactId>adwords-axis</artifactId>
      <version>4.9.0</version>
    </dependency>

    <dependency>
      <groupId>com.google.api-ads</groupId>
      <artifactId>dfp-axis</artifactId>
      <version>4.9.1</version>
    </dependency>

  </dependencies>

MainProject (this also depends on LibraryProject)

<dependencies>
        <dependency>
            <groupId>LibraryProject</groupId>
            <artifactId>LibraryProject</artifactId>
            <version>$MY_VERSION</version>
        </dependency>

        <!-- Should this not come from intelligence-commons? -->
        <dependency>
            <groupId>com.google.api-ads</groupId>
            <artifactId>google-ads</artifactId>
            <version>10.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.25</version>
        </dependency>
        <dependency>
            <groupId>com.google.api-ads</groupId>
            <artifactId>ads-lib</artifactId>
            <version>4.9.1</version>
        </dependency>
        <dependency>
            <groupId>com.google.api-ads</groupId>
            <artifactId>adwords-axis</artifactId>
            <version>4.9.0</version>
        </dependency>
        <dependency>
            <groupId>com.google.api-ads</groupId>
            <artifactId>dfp-axis</artifactId>
            <version>4.9.1</version>
        </dependency>

And, in turn, LibraryProject also has

 <dependency>
            <groupId>com.google.apis</groupId>
            <artifactId>google-api-services-adsense</artifactId>
            <version>v1.4-rev504-1.23.0</version>
            <exclusions>
                <exclusion>
                    <groupId>com.google.guava</groupId>
                    <artifactId>guava-jdk5</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.google.cloud</groupId>
            <artifactId>google-cloud-storage</artifactId>
            <version>1.63.0</version>
        </dependency>
        <dependency>
            <groupId>com.google.auth</groupId>
            <artifactId>google-auth-library-oauth2-http</artifactId>
            <version>0.13.0</version>
        </dependency>
        <dependency>
            <groupId>com.google.api-ads</groupId>
            <artifactId>adwords-axis</artifactId>
            <version>4.9.0</version>
        </dependency>
        <!-- Google Ad Manager Dependencies -->
        <dependency>
            <groupId>com.google.api-ads</groupId>
            <artifactId>ads-lib</artifactId>
            <version>4.9.1</version>
        </dependency>
        <dependency>
            <groupId>com.google.api-ads</groupId>
            <artifactId>dfp-axis</artifactId>
            <version>4.9.1</version>
        </dependency>
        <!-- Google AdMob Dependencies -->
        <!-- https://mvnrepository.com/artifact/com.google.apis/google-api-services-admob -->
        <dependency>
            <groupId>com.google.apis</groupId>
            <artifactId>google-api-services-admob</artifactId>
            <version>v1-rev50-1.25.0</version>
        </dependency>
        <!-- Google Gmail Dependencies -->
        <!-- https://mvnrepository.com/artifact/com.google.oauth-client/google-oauth-client-jetty -->
        <dependency>
            <groupId>com.google.oauth-client</groupId>
            <artifactId>google-oauth-client-jetty</artifactId>
            <version>1.31.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.google.apis/google-api-services-gmail -->
        <dependency>
            <groupId>com.google.apis</groupId>
            <artifactId>google-api-services-gmail</artifactId>
            <version>v1-rev83-1.23.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.google.api-ads/google-ads -->
        <dependency>
            <groupId>com.google.api-ads</groupId>
            <artifactId>google-ads</artifactId>
            <version>10.1.0</version>
        </dependency>

So there is no version conflict in the libraries here, it seems?

Also, why ClassDefNotFound would be an issue here, if the problem is account access? The ClassDefNotFound is a different issue I raised.

So these look

debedb commented 3 years ago

Thank you, I will check all projects against this list and report back.

debedb commented 3 years ago

I was able to overcome the issue by upgrading cprotobuf-java from 3.6.1 to 3.12.0. Will be on the lookout for such things in the future as causes of deadlock (made a gist to do that). Closing this.