googleads / google-ads-java

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

Can the size of google client library be reduced if only a few apis are being used? #581

Open harshjain2525 opened 2 years ago

harshjain2525 commented 2 years ago

Can the size of google client library be reduced if only a few apis are being used? Hello, I am using implementation 'com.google.api-ads:google-ads:17.0.1' in build.gradle to import libraries required. The total size of google ads apis is approximatgely 100 mb. I can see even v9 and v8 is present in the jar, which is of 25 mbs each and is not being used. If I remove them and run the code I am getting error.

Basically, I want to reduce the size of jar. I am only using GetCampaign and campaign_asset apis. I want to remove unnecessary jar files. Please help.

jradcliff commented 2 years ago

Hi,

The library isn't currently designed to only include dependencies from one API version. Could you elaborate on why this poses an issue for you? If you are looking for a smaller JAR for App Engine, please see the following tip in our guides:

https://developers.google.com/google-ads/api/docs/client-libs/java/advanced-usage#app_engine_fails_to_deploy_if_jar_32_mb

Thanks, Josh

jradcliff commented 2 years ago

Hi,

I'm closing this since I haven't heard back in a while. Feel free to reopen if needed.

Thanks

antonyoneill commented 2 years ago

Hi @jradcliff

I've bumped into this problem since updating a few dependencies within my application. I have a relatively straight forward function that receives a batch of conversion events, transforms them, then passes them onto Google Ads.

Since updating the dependencies the JAR for my google cloud function has grown from 107MB to 126MB compressed (or, 423MB to 508MB uncompressed).

Of course that includes other dependency upgrades other than just google-ads, but com/google/ads represents 294MB of 508MB, and is therefore the largest proportion of the dependency tree at almost 58% of the payload. Or, you could also think of it as the Google Ads library taking up 59% of the quota for a cloud function.

It would be very useful, if you were able to reduce the size of the client library in some way.

Fwiw, I'm only using the v10 portion of the library. If you could build specific versions that would be awesome.


Just to give a little more context on what I'm doing here.

I've built the application in Kotlin, I use gradle with Kotlin DSL. Compiling the source, and generate an uber JAR using the ShadowJar plugin from https://github.com/johnrengelman/shadow.

This jar is then uploaded to Google Cloud Functions using the command line, pointing the --source to the JAR output folder.

I am going to experiment with the minimize() function that ShadowJar provides but not sure how that will affect your library.

jradcliff commented 2 years ago

Hi @antonyoneill ,

When you said you are compiling the source, did you mean you are building google-ads-java (this project) from source, or just your own project? If you're building this project, then you could exclude older API versions from the library by removing their corresponding include statements from settings.gradle. There may be tests that won't compile, but you could exclude them if that's the only issue you encounter with this approach.

Thanks, Josh

antonyoneill commented 2 years ago

Hey,

Apologies, I meant compiling my own app for deployment into Cloud Functions. I've got it set up to produce a uber/shadow jar containing my source, plus the dependencies. I'm not overly familiar with Cloud Functions so haven't wanted to get side tracked into figuring out the dependency management.

FWIW I have used the minimize() function in the ShadowJar plugin and it has decreased the size of the resulting jar - however I'm yet (to get a minute) to try it out to see if it actually functions.

I don't really want to go down the route of maintaining my own fork of this project to remove the older versions, which I'm sure you'll appreciate.

Thanks! Antony

jradcliff commented 2 years ago

Hi Antony,

Thanks for the reply. I thought you might already be building from source, in which case the approach I mentioned would just be an additional step. Given that you're not doing that already, I completely understand why (and agree that) forking is not a great option.

Cheers, Josh

antonyoneill commented 2 years ago

Unfortunately, that minimize() function wasn't useful in this situation - it seems there are a lot of dependencies that must be loosely referenced which were removed and essentially prevented the application from functioning whatsoever.

I've taken to a relatively drastic action of removing the v8 and v9 files from the resulting jar. I've not started on the implementation part where I actually use the Ads API yet, but I'll be in touch when I know if it works.


For those interested, this is roughly what I've got - of course this is very project and setup specific. ymmv

# ... your build script/pipeline

./gradlew my-module:shadowJar

zip -d my-module/build/libs/my-module.jar "com/google/ads/googleads/v8/*"
zip -d my-module/build/libs/my-module.jar "com/google/ads/googleads/v9/*"

gcloud beta functions deploy my-module \
 --runtime java11 \
 --source "$cwd"/build/libs/ \
  # --etc
antonyoneill commented 2 years ago

So, a little update on this now that I'm beginning to test the cloud function in-place.. I'm failing at the first hurdle to even instantiate the function, perhaps I was too destructive with the pruning.

Failed to execute my_app.entry_upload.Handler
java.lang.NoClassDefFoundError: Could not initialize class com.google.ads.googleads.lib.catalog.GeneratedCatalog
    at com.google.ads.googleads.lib.catalog.ApiCatalog.getDefault(ApiCatalog.java:32)
    at com.google.ads.googleads.lib.GoogleAdsClient$Builder.build(GoogleAdsClient.java:611)
    at my_app.conversion.googleads.api.APIGoogleAdsGateway.uploadClickConversions(APIGoogleAdsGateway.kt:38)
    at my_app.conversion.googleads.UploadGoogleAdConversionService.upload(UploadGoogleAdConversionService.kt:74)
    at my_app.my_module.Handler.handleTask(Handler.kt:99)
    at my_app.my_module.Handler.service(Handler.kt:54)
    at com.google.cloud.functions.invoker.HttpFunctionExecutor.service(HttpFunctionExecutor.java:69)

That class file does exist within the deployable JAR, so I'm not confident that it's related to the pruning... But I thought subscribers of this ticket may be interested.