googleads / google-ads-java

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

java.lang.NoClassDefFoundError: com/google/api/FieldBehaviorProto #397

Closed debedb closed 3 years ago

debedb commented 3 years ago

I'm trying to run the GetAccountHierarchy example. It works perfectly fine when run ass part of a small example project (call it SampleProject) with the following pom.xml:

  <dependencies>
     <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>
    <dependency>
      <groupId>com.google.api-ads</groupId>
      <artifactId>google-ads</artifactId>
      <version>10.1.0</version>
    </dependency>
  </dependencies>

However, when used in a larger project (call it ProdProject -- here it is hard to isolate a reproducible case) the error in the subject appears, with the following stack trace:

java.lang.NoClassDefFoundError: com/google/api/FieldBehaviorProto
    at com.google.ads.googleads.v6.resources.CustomerClientProto.<clinit>(CustomerClientProto.java:62)
    at com.google.ads.googleads.v6.resources.CustomerClient.getDescriptor(CustomerClient.java:139)
    at com.google.ads.googleads.v6.resources.CustomerClient.hashCode(CustomerClient.java:740)
    at java.util.HashMap.hash(HashMap.java:339)
    at java.util.HashMap.put(HashMap.java:612)
    at mypkg.GetAccountHierarchy.createCustomerClientToHierarchy(GetAccountHierarchy.java:271)
    at mypkg.GetAccountHierarchy.gatherHierarchies(GetAccountHierarchy.java:124)

Because there's some formatting differences between the example here and as run, clarifying that GetAccountHierarchy.java:271 is

  customerClientToHierarchy.put( rootCustomerClient, customerIdsToChildAccounts );

and GetAccountHierarchy.java:124 is

         Map<CustomerClient, Multimap<Long, CustomerClient>> customerClientToHierarchy = createCustomerClientToHierarchy( seedCustomerId );

This ProdProject does not directly reference the api-ads libraries, but instead references LibProject which in turn has the following google libraries

        <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>
        <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>
        <dependency>
            <groupId>com.google.apis</groupId>
            <artifactId>google-api-services-admob</artifactId>
            <version>v1-rev50-1.25.0</version>
        </dependency>
        <dependency>
            <groupId>com.google.oauth-client</groupId>
            <artifactId>google-oauth-client-jetty</artifactId>
            <version>1.31.0</version>
        </dependency>
        <dependency>
            <groupId>com.google.apis</groupId>
            <artifactId>google-api-services-gmail</artifactId>
            <version>v1-rev83-1.23.0</version>
        </dependency>
        <dependency>
            <groupId>com.google.api-ads</groupId>
            <artifactId>google-ads</artifactId>
            <version>10.1.0</version>
        </dependency>

As a workaround, adding the following to the pom.xml of the ProdProject works:

<dependency>
            <groupId>com.google.api.grpc</groupId>
            <artifactId>proto-google-common-protos</artifactId>
            <version>2.0.1</version>
        </dependency>

However, it would be good to understand what the problem is and why the SampleProject works without this dependency.

nwbirnie commented 3 years ago

I'm guessing that your production project has a transitive dependency on proto-google-common-protos from a version prior to when FieldBehaviourProto was added.

Can you run mvn dependency:tree -Dverbose on the prod project and check to see if there's a conflict on proto-google-common-protos? If so that would explain the difference in behaviour, since maven doesn't know which version to load.

debedb commented 3 years ago

Right, I should have done that first. The

com.google.api.grpc:proto-google-common-protos:jar:1.14.0

which doesn't have the field yet, is brought in by

  <dependency>
            <groupId>com.google.cloud</groupId>
            <artifactId>google-cloud-storage</artifactId>
            <version>1.63.0</version>
        </dependency>

I'll close this.