Add support for Provider#configure in JDK 9+

Starting in JDK 9 the Provider single-arg configuration constructor
has been replaced with a #configure(String) method to be invoked
after the no-arg constructor. This commit will first attempt the
original behavior to support systems using an older JDK; if the
single-arg configuration constructor is not available then the new
API will be used.

Bug: 173837265
Test: gradlew test
Change-Id: I22d1143e76d1552d59e3cd6fadef66d9001e8009
diff --git a/src/apksigner/java/com/android/apksigner/ApkSignerTool.java b/src/apksigner/java/com/android/apksigner/ApkSignerTool.java
index 2f4e680..cb01a55 100644
--- a/src/apksigner/java/com/android/apksigner/ApkSignerTool.java
+++ b/src/apksigner/java/com/android/apksigner/ApkSignerTool.java
@@ -1071,10 +1071,19 @@
             }
             Provider provider;
             if (constructorParam != null) {
-                // Single-arg Provider constructor
-                provider =
-                        (Provider) providerClass.getConstructor(String.class)
-                                .newInstance(constructorParam);
+                try {
+                    // Single-arg Provider constructor
+                    provider =
+                            (Provider) providerClass.getConstructor(String.class)
+                                    .newInstance(constructorParam);
+                } catch (NoSuchMethodException e) {
+                    // Starting from JDK 9 the single-arg constructor accepting the configuration
+                    // has been replaced by a configure(String) method to be invoked after
+                    // instantiating the Provider with the no-arg constructor.
+                    provider = (Provider) providerClass.getConstructor().newInstance();
+                    provider = (Provider) providerClass.getMethod("configure", String.class)
+                            .invoke(provider, constructorParam);
+                }
             } else {
                 // No-arg Provider constructor
                 provider = (Provider) providerClass.getConstructor().newInstance();
diff --git a/src/apksigner/java/com/android/apksigner/SignerParams.java b/src/apksigner/java/com/android/apksigner/SignerParams.java
index 8c8b550..515cd41 100644
--- a/src/apksigner/java/com/android/apksigner/SignerParams.java
+++ b/src/apksigner/java/com/android/apksigner/SignerParams.java
@@ -209,10 +209,19 @@
             }
             Provider ksProvider;
             if (keystoreProviderArg != null) {
-                // Single-arg Provider constructor
-                ksProvider =
-                        (Provider) ksProviderClass.getConstructor(String.class)
-                                .newInstance(keystoreProviderArg);
+                try {
+                    // Single-arg Provider constructor
+                    ksProvider =
+                            (Provider) ksProviderClass.getConstructor(String.class)
+                                    .newInstance(keystoreProviderArg);
+                } catch (NoSuchMethodException e) {
+                    // Starting from JDK 9 the single-arg constructor accepting the configuration
+                    // has been replaced by a configure(String) method to be invoked after
+                    // instantiating the Provider with the no-arg constructor.
+                    ksProvider = (Provider) ksProviderClass.getConstructor().newInstance();
+                    ksProvider = (Provider) ksProviderClass.getMethod("configure",
+                            String.class).invoke(ksProvider, keystoreProviderArg);
+                }
             } else {
                 // No-arg Provider constructor
                 ksProvider = (Provider) ksProviderClass.getConstructor().newInstance();