Home » Android » java – How to debug a third-party Gradle plugin?

java – How to debug a third-party Gradle plugin?

Posted by: admin June 15, 2020 Leave a comment

Questions:

I’m trying to sign an Android AAR artifact using the gradle signing plugin. Unfortunately, I’m getting a rather unhelpful NullPointerException in the process:

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':library:signArchives'.
> java.lang.NullPointerException (no error message)

* Try:
Run with --info or --debug option to get more log output.

* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':library:signArchives'.
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:69)
        [...snip...]
        at org.gradle.launcher.Main.main(Main.java:37)
        at org.gradle.launcher.bootstrap.ProcessBootstrap.runNoExit(ProcessBootstrap.java:50)
        at org.gradle.launcher.bootstrap.ProcessBootstrap.run(ProcessBootstrap.java:32)
        at org.gradle.launcher.GradleMain.main(GradleMain.java:23)
        at org.gradle.wrapper.BootstrapMainStarter.start(BootstrapMainStarter.java:33)
        at org.gradle.wrapper.WrapperExecutor.execute(WrapperExecutor.java:130)
        at org.gradle.wrapper.GradleWrapperMain.main(GradleWrapperMain.java:48)
Caused by: java.lang.NullPointerException
        at org.bouncycastle.openpgp.PGPSignatureGenerator.initSign(Unknown Source)
        at org.bouncycastle.openpgp.PGPSignatureGenerator.initSign(Unknown Source)
        at org.bouncycastle.openpgp.PGPSignatureGenerator$initSign.call(Unknown Source)
        at org.gradle.plugins.signing.signatory.pgp.PgpSignatory.createSignatureGenerator(PgpSignatory.groovy:54)
        at org.gradle.plugins.signing.signatory.pgp.PgpSignatory.sign(PgpSignatory.groovy:64)
        [...snip...]
        ... 52 more


BUILD FAILED

What’s the easiest way to debug this exception? Is there a way to attach a debugger to gradle? Can I build the signing plugin, insert some logging statements and tell my build to pick up my custom version instead of the one it ships with?

How to&Answers:

According to a thread in the gradle forums there is a somewhat secret org.gradle.debug-flag that allows you to attach a debugger.

gradle someTask --no-daemon -Dorg.gradle.debug=true

For the hotfixing/custom-plugin it should be enough to put your copied & modified plugin in rootProjectDir/buildSrc/src/main/groovy. You can read more about writing a custom plugin on the Gradle site.

Answer:

This is how I did it using IntelliJ – Android Studio is based on IntelliJ so it should be the same, and other IDEs should be similar:

Download the correct version of the source code of the buggy Gradle plugin, or clone/access its version control repository and check out the relevant branch or tag corresponding to the version of the buggy Gradle plugin you are using. Import the code into IntelliJ by using File -> New project from existing sources. Then run, at the command line:

./gradlew someTask -Dorg.gradle.debug=true --no-daemon

and create a new remote debugging connection using port 5005, set your initial breakpoint, and start it.

Alternatively, you can use the Gradle daemon by instead doing ./gradlew -Dorg.gradle.jvmargs="standard JVM debugging arguments", and this way you can use any debugging port you like, but I have not tested this. For example:

./gradlew \
  -Dorg.gradle.jvmargs="-agentlib:jdwp=transport=dt_socket,server=y,address=5005,suspend=y" \
  someTask