Make apksig compatible with Java 7 am: caf0df53f7

Change-Id: Idd1414e404ffca0962eb745bf154eb9306155b54
diff --git a/src/apksigner/java/com/android/apksigner/ApkSignerTool.java b/src/apksigner/java/com/android/apksigner/ApkSignerTool.java
index fe29987..f864595 100644
--- a/src/apksigner/java/com/android/apksigner/ApkSignerTool.java
+++ b/src/apksigner/java/com/android/apksigner/ApkSignerTool.java
@@ -713,7 +713,6 @@
         File outputKeyLineage = null;
         String optionName;
         OptionsParser optionsParser = new OptionsParser(params);
-        SigningCertificateLineage lineage = null;
         List<SignerParams> signers = new ArrayList<>(1);
         while ((optionName = optionsParser.nextOption()) != null) {
             if (("help".equals(optionName)) || ("h".equals(optionName))) {
@@ -739,7 +738,7 @@
         if (inputKeyLineage == null) {
             throw new ParameterException("Input lineage file parameter not present");
         }
-        lineage = getLineageFromInputFile(inputKeyLineage);
+        SigningCertificateLineage lineage = getLineageFromInputFile(inputKeyLineage);
 
         try (PasswordRetriever passwordRetriever = new PasswordRetriever()) {
             for (int i = 0; i < signers.size(); i++) {
diff --git a/src/main/java/com/android/apksig/ApkSigner.java b/src/main/java/com/android/apksig/ApkSigner.java
index 559c0e3..3b63744 100644
--- a/src/main/java/com/android/apksig/ApkSigner.java
+++ b/src/main/java/com/android/apksig/ApkSigner.java
@@ -576,7 +576,7 @@
         }
     }
 
-    private long outputDataToOutputApk(
+    private static long outputDataToOutputApk(
             String entryName,
             byte[] uncompressedData,
             long localFileHeaderOffset,
@@ -672,7 +672,7 @@
                         outputOffset + inputRecord.getExtraFieldStartOffsetInsideRecord(),
                         dataAlignmentMultiple);
         long dataOffset =
-                inputRecord.getDataStartOffsetInRecord()
+                (long) inputRecord.getDataStartOffsetInRecord()
                         + aligningExtra.remaining()
                         - inputRecord.getExtra().remaining();
         return new OutputSizeAndDataOffset(
diff --git a/src/main/java/com/android/apksig/ApkVerifier.java b/src/main/java/com/android/apksig/ApkVerifier.java
index 3d98a38..76a8d74 100644
--- a/src/main/java/com/android/apksig/ApkVerifier.java
+++ b/src/main/java/com/android/apksig/ApkVerifier.java
@@ -215,7 +215,7 @@
                     SUPPORTED_APK_SIG_SCHEME_NAMES.get(
                             ApkSigningBlockUtils.VERSION_APK_SIGNATURE_SCHEME_V2));
         } else {
-            supportedSchemeNames = Collections.EMPTY_MAP;
+            supportedSchemeNames = Collections.emptyMap();
         }
         // Android N and newer attempts to verify APKs using the APK Signing Block, which can
         // include v2 and/or v3 signatures.  If none is found, it falls back to JAR signature
@@ -292,14 +292,14 @@
                 try {
                     List<CentralDirectoryRecord> cdRecords =
                             V1SchemeVerifier.parseZipCentralDirectory(apk, zipSections);
-                    CentralDirectoryRecord sourceStampCdRecord =
-                            cdRecords.stream()
-                                    .filter(
-                                            cdRecord ->
-                                                    SOURCE_STAMP_CERTIFICATE_HASH_ZIP_ENTRY_NAME
-                                                            .equals(cdRecord.getName()))
-                                    .findAny()
-                                    .orElse(null);
+                    CentralDirectoryRecord sourceStampCdRecord = null;
+                    for (CentralDirectoryRecord cdRecord : cdRecords) {
+                        if (SOURCE_STAMP_CERTIFICATE_HASH_ZIP_ENTRY_NAME.equals(
+                                cdRecord.getName())) {
+                            sourceStampCdRecord = cdRecord;
+                            break;
+                        }
+                    }
                     // If SourceStamp file is found inside the APK, there must be a SourceStamp
                     // block in the APK signing block as well.
                     if (sourceStampCdRecord != null) {
@@ -378,7 +378,7 @@
                 try {
                     v1SignerCerts.add(new ByteArray(signer.getCertificate().getEncoded()));
                 } catch (CertificateEncodingException e) {
-                    throw new RuntimeException(
+                    throw new IllegalStateException(
                             "Failed to encode JAR signer " + signer.getName() + " certs", e);
                 }
             }
@@ -386,7 +386,7 @@
                 try {
                     v2SignerCerts.add(new ByteArray(signer.getCertificate().getEncoded()));
                 } catch (CertificateEncodingException e) {
-                    throw new RuntimeException(
+                    throw new IllegalStateException(
                             "Failed to encode APK Signature Scheme v2 signer (index: "
                                     + signer.getIndex() + ") certs",
                             e);
@@ -498,9 +498,18 @@
                     v3Signers.get(0).getContentDigests();
             List<ApkSigningBlockUtils.Result.SignerInfo.ContentDigest> v3DigestsFromV4 =
                     v4Signers.get(0).getContentDigests();
-            if (v3DigestsFromV4.size() != 1
-                    || v3DigestsFromV3.stream().noneMatch(
-                            d -> Arrays.equals(d.getValue(), v3DigestsFromV4.get(0).getValue()))) {
+            if (v3DigestsFromV4.size() != 1) {
+                result.addError(Issue.V4_SIG_V3_DIGESTS_MISMATCH);
+            }
+            boolean foundV3DigestMatch = false;
+            for (ApkSigningBlockUtils.Result.SignerInfo.ContentDigest v3DigestFromV3 :
+                    v3DigestsFromV3) {
+                if (Arrays.equals(v3DigestFromV3.getValue(), v3DigestsFromV4.get(0).getValue())) {
+                    foundV3DigestMatch = true;
+                    break;
+                }
+            }
+            if (!foundV3DigestMatch) {
                 result.addError(Issue.V4_SIG_V3_DIGESTS_MISMATCH);
             }
         }
@@ -1181,10 +1190,6 @@
                 return mCertificates.isEmpty() ? null : mCertificates.get(0);
             }
 
-            private void addError(Issue msg, Object... parameters) {
-                mErrors.add(new IssueWithParams(msg, parameters));
-            }
-
             public boolean containsErrors() {
                 return !mErrors.isEmpty();
             }
@@ -2352,10 +2357,7 @@
             if (this == obj) {
                 return true;
             }
-            if (obj == null) {
-                return false;
-            }
-            if (getClass() != obj.getClass()) {
+            if (!(obj instanceof ByteArray)) {
                 return false;
             }
             ByteArray other = (ByteArray) obj;
diff --git a/src/main/java/com/android/apksig/DefaultApkSignerEngine.java b/src/main/java/com/android/apksig/DefaultApkSignerEngine.java
index bbd6933..0e0b554 100644
--- a/src/main/java/com/android/apksig/DefaultApkSignerEngine.java
+++ b/src/main/java/com/android/apksig/DefaultApkSignerEngine.java
@@ -54,6 +54,7 @@
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
@@ -485,18 +486,19 @@
             if (V1SchemeSigner.isJarEntryDigestNeededInManifest(entry.getKey())
                     && isDebuggable(entryName)) {
 
-                Optional<V1SchemeVerifier.NamedDigest> extractedDigest =
+                V1SchemeVerifier.NamedDigest extractedDigest = null;
+                Collection<V1SchemeVerifier.NamedDigest> digestsToVerify =
                         V1SchemeVerifier.getDigestsToVerify(
-                                        entry.getValue(),
-                                        "-Digest",
-                                        mMinSdkVersion,
-                                        Integer.MAX_VALUE)
-                                .stream()
-                                .filter(d -> d.jcaDigestAlgorithm == alg)
-                                .findFirst();
-
-                extractedDigest.ifPresent(
-                        namedDigest -> mOutputJarEntryDigests.put(entryName, namedDigest.digest));
+                                entry.getValue(), "-Digest", mMinSdkVersion, Integer.MAX_VALUE);
+                for (V1SchemeVerifier.NamedDigest digestToVerify : digestsToVerify) {
+                    if (digestToVerify.jcaDigestAlgorithm.equals(alg)) {
+                        extractedDigest = digestToVerify;
+                        break;
+                    }
+                }
+                if (extractedDigest != null) {
+                    mOutputJarEntryDigests.put(entryName, extractedDigest.digest);
+                }
             }
         }
         return mOutputJarEntryDigests.keySet();
diff --git a/src/main/java/com/android/apksig/internal/apk/ApkSigningBlockUtils.java b/src/main/java/com/android/apksig/internal/apk/ApkSigningBlockUtils.java
index 143ee3f..944b9b8 100644
--- a/src/main/java/com/android/apksig/internal/apk/ApkSigningBlockUtils.java
+++ b/src/main/java/com/android/apksig/internal/apk/ApkSigningBlockUtils.java
@@ -431,10 +431,13 @@
             DataSource centralDir,
             DataSource eocd) throws IOException, NoSuchAlgorithmException, DigestException {
         Map<ContentDigestAlgorithm, byte[]> contentDigests = new HashMap<>();
-        Set<ContentDigestAlgorithm> oneMbChunkBasedAlgorithm = digestAlgorithms.stream()
-                .filter(a -> a == ContentDigestAlgorithm.CHUNKED_SHA256 ||
-                             a == ContentDigestAlgorithm.CHUNKED_SHA512)
-                .collect(Collectors.toSet());
+        Set<ContentDigestAlgorithm> oneMbChunkBasedAlgorithm = new HashSet<>();
+        for (ContentDigestAlgorithm digestAlgorithm : digestAlgorithms) {
+            if (digestAlgorithm == ContentDigestAlgorithm.CHUNKED_SHA256
+                    || digestAlgorithm == ContentDigestAlgorithm.CHUNKED_SHA512) {
+                oneMbChunkBasedAlgorithm.add(digestAlgorithm);
+            }
+        }
         computeOneMbChunkContentDigests(
                 executor,
                 oneMbChunkBasedAlgorithm,
@@ -698,7 +701,7 @@
                                     i));
                 }
                 chunkCounts[i] = (int)chunkCount;
-                totalChunkCount += chunkCount;
+                totalChunkCount = (int) (totalChunkCount + chunkCount);
             }
             this.totalChunkCount = totalChunkCount;
             nextIndex = new AtomicInteger(0);
@@ -1182,10 +1185,12 @@
         if (bestSigAlgorithmOnSdkVersion.isEmpty()) {
             throw new NoSupportedSignaturesException("No supported signature");
         }
-        return bestSigAlgorithmOnSdkVersion.values().stream()
-                .sorted((sig1, sig2) -> Integer.compare(
-                        sig1.algorithm.getId(), sig2.algorithm.getId()))
-                .collect(Collectors.toList());
+        List<SupportedSignature> signaturesToVerify =
+                new ArrayList<>(bestSigAlgorithmOnSdkVersion.values());
+        Collections.sort(
+                signaturesToVerify,
+                (sig1, sig2) -> Integer.compare(sig1.algorithm.getId(), sig2.algorithm.getId()));
+        return signaturesToVerify;
     }
 
     public static class NoSupportedSignaturesException extends Exception {
@@ -1279,7 +1284,7 @@
      *     //       signatureAlgorithm
      *     //       signature
      *
-     * @throws Asn1EncodingException
+     * @throws Asn1EncodingException if the ASN.1 structure could not be encoded
      */
     public static byte[] generatePkcs7DerEncodedMessage(
             byte[] signatureBytes, ByteBuffer data, List<X509Certificate> signerCerts,
@@ -1345,7 +1350,7 @@
         /** Whether the APK's APK Signature Scheme signature verifies. */
         public boolean verified;
 
-        public final List<SignerInfo> signers = new ArrayList<>();
+        public final List<Result.SignerInfo> signers = new ArrayList<>();
         public SigningCertificateLineage signingCertificateLineage = null;
         private final List<ApkVerifier.IssueWithParams> mWarnings = new ArrayList<>();
         private final List<ApkVerifier.IssueWithParams> mErrors = new ArrayList<>();
@@ -1359,7 +1364,7 @@
                 return true;
             }
             if (!signers.isEmpty()) {
-                for (SignerInfo signer : signers) {
+                for (Result.SignerInfo signer : signers) {
                     if (signer.containsErrors()) {
                         return true;
                     }
@@ -1373,7 +1378,7 @@
                 return true;
             }
             if (!signers.isEmpty()) {
-                for (SignerInfo signer : signers) {
+                for (Result.SignerInfo signer : signers) {
                     if (signer.containsWarnings()) {
                         return true;
                     }
diff --git a/src/main/java/com/android/apksig/internal/apk/stamp/SourceStampSigner.java b/src/main/java/com/android/apksig/internal/apk/stamp/SourceStampSigner.java
index 0749ef8..d7e10e7 100644
--- a/src/main/java/com/android/apksig/internal/apk/stamp/SourceStampSigner.java
+++ b/src/main/java/com/android/apksig/internal/apk/stamp/SourceStampSigner.java
@@ -29,6 +29,8 @@
 import java.security.NoSuchAlgorithmException;
 import java.security.SignatureException;
 import java.security.cert.CertificateEncodingException;
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
@@ -58,11 +60,11 @@
             throw new SignatureException("No certificates configured for signer");
         }
 
-        List<Pair<Integer, byte[]>> digests =
-                digestInfo.entrySet().stream()
-                        .sorted(Comparator.comparing(e -> e.getKey().getId()))
-                        .map(e -> Pair.of(e.getKey().getId(), e.getValue()))
-                        .collect(Collectors.toList());
+        List<Pair<Integer, byte[]>> digests = new ArrayList<>();
+        for (Map.Entry<ContentDigestAlgorithm, byte[]> digest : digestInfo.entrySet()) {
+            digests.add(Pair.of(digest.getKey().getId(), digest.getValue()));
+        }
+        Collections.sort(digests, Comparator.comparing(Pair::getFirst));
 
         SourceStampBlock sourceStampBlock = new SourceStampBlock();
 
diff --git a/src/main/java/com/android/apksig/internal/apk/stamp/SourceStampVerifier.java b/src/main/java/com/android/apksig/internal/apk/stamp/SourceStampVerifier.java
index 68d225c..3590c71 100644
--- a/src/main/java/com/android/apksig/internal/apk/stamp/SourceStampVerifier.java
+++ b/src/main/java/com/android/apksig/internal/apk/stamp/SourceStampVerifier.java
@@ -36,7 +36,6 @@
 import java.nio.ByteBuffer;
 import java.security.InvalidAlgorithmParameterException;
 import java.security.InvalidKeyException;
-import java.security.KeyFactory;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.security.PublicKey;
@@ -46,9 +45,10 @@
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
 import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.X509EncodedKeySpec;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
@@ -136,7 +136,7 @@
                     maxSdkVersion);
             result.verified = !result.containsErrors() && !result.containsWarnings();
         } catch (CertificateException e) {
-            throw new RuntimeException("Failed to obtain X.509 CertificateFactory", e);
+            throw new IllegalStateException("Failed to obtain X.509 CertificateFactory", e);
         } catch (ApkFormatException | BufferUnderflowException e) {
             signerInfo.addWarning(ApkVerifier.Issue.SOURCE_STAMP_MALFORMED_SIGNATURE);
         }
@@ -160,11 +160,12 @@
             int minSdkVersion,
             int maxSdkVersion)
             throws ApkFormatException, NoSuchAlgorithmException {
-        List<Pair<Integer, byte[]>> digests =
-                apkContentDigests.entrySet().stream()
-                        .sorted(Comparator.comparing(e -> e.getKey().getId()))
-                        .map(e -> Pair.of(e.getKey().getId(), e.getValue()))
-                        .collect(Collectors.toList());
+        List<Pair<Integer, byte[]>> digests = new ArrayList<>();
+        for (Map.Entry<ContentDigestAlgorithm, byte[]> apkContentDigest :
+                apkContentDigests.entrySet()) {
+            digests.add(Pair.of(apkContentDigest.getKey().getId(), apkContentDigest.getValue()));
+        }
+        Collections.sort(digests, Comparator.comparing(Pair::getFirst));
         byte[] digestBytes =
                 encodeAsSequenceOfLengthPrefixedPairsOfIntAndLengthPrefixedBytes(digests);
 
diff --git a/src/main/java/com/android/apksig/internal/apk/v1/V1SchemeSigner.java b/src/main/java/com/android/apksig/internal/apk/v1/V1SchemeSigner.java
index a757f62..89f16d5 100644
--- a/src/main/java/com/android/apksig/internal/apk/v1/V1SchemeSigner.java
+++ b/src/main/java/com/android/apksig/internal/apk/v1/V1SchemeSigner.java
@@ -16,37 +16,20 @@
 
 package com.android.apksig.internal.apk.v1;
 
-import static com.android.apksig.internal.asn1.Asn1DerEncoder.ASN1_DER_NULL;
-import static com.android.apksig.internal.oid.OidConstants.OID_DIGEST_SHA1;
-import static com.android.apksig.internal.oid.OidConstants.OID_DIGEST_SHA256;
-import static com.android.apksig.internal.oid.OidConstants.OID_SIG_DSA;
-import static com.android.apksig.internal.oid.OidConstants.OID_SIG_EC_PUBLIC_KEY;
-import static com.android.apksig.internal.oid.OidConstants.OID_SIG_RSA;
-import static com.android.apksig.internal.oid.OidConstants.OID_SIG_SHA256_WITH_DSA;
 import static com.android.apksig.internal.pkcs7.AlgorithmIdentifier.getSignerInfoDigestAlgorithmOid;
 import static com.android.apksig.internal.pkcs7.AlgorithmIdentifier.getSignerInfoSignatureAlgorithm;
 
 import com.android.apksig.apk.ApkFormatException;
 import com.android.apksig.internal.apk.ApkSigningBlockUtils;
-import com.android.apksig.internal.asn1.Asn1DerEncoder;
 import com.android.apksig.internal.asn1.Asn1EncodingException;
-import com.android.apksig.internal.asn1.Asn1OpaqueObject;
-import com.android.apksig.internal.asn1.ber.BerEncoding;
 import com.android.apksig.internal.jar.ManifestWriter;
 import com.android.apksig.internal.jar.SignatureFileWriter;
 import com.android.apksig.internal.pkcs7.AlgorithmIdentifier;
-import com.android.apksig.internal.pkcs7.ContentInfo;
-import com.android.apksig.internal.pkcs7.EncapsulatedContentInfo;
-import com.android.apksig.internal.pkcs7.IssuerAndSerialNumber;
-import com.android.apksig.internal.pkcs7.Pkcs7Constants;
-import com.android.apksig.internal.pkcs7.SignedData;
-import com.android.apksig.internal.pkcs7.SignerIdentifier;
-import com.android.apksig.internal.pkcs7.SignerInfo;
 import com.android.apksig.internal.util.Pair;
+
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
-import java.nio.ByteBuffer;
 import java.security.InvalidKeyException;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
@@ -69,7 +52,6 @@
 import java.util.TreeMap;
 import java.util.jar.Attributes;
 import java.util.jar.Manifest;
-import javax.security.auth.x500.X500Principal;
 
 /**
  * APK signer which uses JAR signing (aka v1 signing scheme).
diff --git a/src/main/java/com/android/apksig/internal/apk/v1/V1SchemeVerifier.java b/src/main/java/com/android/apksig/internal/apk/v1/V1SchemeVerifier.java
index 1570752..111ac71 100644
--- a/src/main/java/com/android/apksig/internal/apk/v1/V1SchemeVerifier.java
+++ b/src/main/java/com/android/apksig/internal/apk/v1/V1SchemeVerifier.java
@@ -16,11 +16,6 @@
 
 package com.android.apksig.internal.apk.v1;
 
-import static com.android.apksig.internal.oid.OidConstants.OID_SIG_DSA;
-import static com.android.apksig.internal.oid.OidConstants.OID_SIG_EC_PUBLIC_KEY;
-import static com.android.apksig.internal.oid.OidConstants.OID_SIG_RSA;
-import static com.android.apksig.internal.oid.OidConstants.OID_TO_JCA_DIGEST_ALG;
-import static com.android.apksig.internal.oid.OidConstants.OID_TO_JCA_SIGNATURE_ALG;
 import static com.android.apksig.internal.oid.OidConstants.getSigAlgSupportedApiLevels;
 import static com.android.apksig.internal.pkcs7.AlgorithmIdentifier.getJcaDigestAlgorithm;
 import static com.android.apksig.internal.pkcs7.AlgorithmIdentifier.getJcaSignatureAlgorithm;
@@ -41,18 +36,14 @@
 import com.android.apksig.internal.oid.OidConstants;
 import com.android.apksig.internal.pkcs7.Attribute;
 import com.android.apksig.internal.pkcs7.ContentInfo;
-import com.android.apksig.internal.pkcs7.IssuerAndSerialNumber;
 import com.android.apksig.internal.pkcs7.Pkcs7Constants;
 import com.android.apksig.internal.pkcs7.Pkcs7DecodingException;
 import com.android.apksig.internal.pkcs7.SignedData;
-import com.android.apksig.internal.pkcs7.SignerIdentifier;
 import com.android.apksig.internal.pkcs7.SignerInfo;
 import com.android.apksig.internal.util.AndroidSdkVersion;
 import com.android.apksig.internal.util.ByteBufferUtils;
-import com.android.apksig.internal.util.GuaranteedEncodedFormX509Certificate;
 import com.android.apksig.internal.util.InclusiveIntRange;
 import com.android.apksig.internal.util.Pair;
-import com.android.apksig.internal.util.X509CertificateUtils;
 import com.android.apksig.internal.zip.CentralDirectoryRecord;
 import com.android.apksig.internal.zip.LocalFileRecord;
 import com.android.apksig.util.DataSinks;
@@ -60,7 +51,6 @@
 import com.android.apksig.zip.ZipFormatException;
 
 import java.io.IOException;
-import java.math.BigInteger;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.security.InvalidKeyException;
@@ -86,8 +76,6 @@
 import java.util.StringTokenizer;
 import java.util.jar.Attributes;
 
-import javax.security.auth.x500.X500Principal;
-
 /**
  * APK verifier which uses JAR signing (aka v1 signing scheme).
  *
@@ -1317,13 +1305,10 @@
         Collections.sort(
                 cdRecordsSortedByLocalFileHeaderOffset,
                 CentralDirectoryRecord.BY_LOCAL_FILE_HEADER_OFFSET_COMPARATOR);
-        Set<String> manifestEntryNamesMissingFromApk =
-                new HashSet<>(entryNameToManifestSection.keySet());
         List<Signer> firstSignedEntrySigners = null;
         String firstSignedEntryName = null;
         for (CentralDirectoryRecord cdRecord : cdRecordsSortedByLocalFileHeaderOffset) {
             String entryName = cdRecord.getName();
-            manifestEntryNamesMissingFromApk.remove(entryName);
             if (!isJarEntryDigestNeededInManifest(entryName)) {
                 continue;
             }
diff --git a/src/main/java/com/android/apksig/internal/apk/v4/V4SchemeVerifier.java b/src/main/java/com/android/apksig/internal/apk/v4/V4SchemeVerifier.java
index 9c93c10..96294da 100644
--- a/src/main/java/com/android/apksig/internal/apk/v4/V4SchemeVerifier.java
+++ b/src/main/java/com/android/apksig/internal/apk/v4/V4SchemeVerifier.java
@@ -17,9 +17,6 @@
 package com.android.apksig.internal.apk.v4;
 
 import static com.android.apksig.internal.apk.ApkSigningBlockUtils.toHex;
-import static com.android.apksig.internal.apk.SignatureAlgorithm.VERITY_DSA_WITH_SHA256;
-import static com.android.apksig.internal.apk.SignatureAlgorithm.VERITY_ECDSA_WITH_SHA256;
-import static com.android.apksig.internal.apk.SignatureAlgorithm.VERITY_RSA_PKCS1_V1_5_WITH_SHA256;
 import static com.android.apksig.internal.pkcs7.AlgorithmIdentifier.getJcaSignatureAlgorithm;
 import static com.android.apksig.internal.x509.Certificate.findCertificate;
 import static com.android.apksig.internal.x509.Certificate.parseCertificates;
@@ -150,7 +147,6 @@
             }
             signedData = Asn1BerParser.parse(contentInfo.content.getEncoded(), SignedData.class);
         } catch (Asn1DecodingException e) {
-            e.printStackTrace();
             result.addError(Issue.V4_SIG_MALFORMED_PKCS7, e);
             return result;
         }
@@ -219,11 +215,9 @@
         }
         final boolean[] keyUsageExtension = signingCertificate.getKeyUsage();
         if (keyUsageExtension != null) {
-            boolean digitalSignature =
-                    (keyUsageExtension.length >= 1) && (keyUsageExtension[0]);
-            boolean nonRepudiation =
-                    (keyUsageExtension.length >= 2) && (keyUsageExtension[1]);
-            if ((!digitalSignature) && (!nonRepudiation)) {
+            boolean digitalSignature = (keyUsageExtension.length >= 1) && keyUsageExtension[0];
+            boolean nonRepudiation = (keyUsageExtension.length >= 2) && keyUsageExtension[1];
+            if (!digitalSignature && !nonRepudiation) {
                 result.addError(Issue.V4_SIG_MALFORMED_CERTIFICATE,
                         "Signing certificate not authorized for use in digital signatures"
                                 + ": keyUsage extension missing digitalSignature and"
@@ -232,15 +226,12 @@
             }
         }
 
-        Signature s = null;
+        Signature s;
         try {
             final String jcaSignatureAlgorithm = getJcaSignatureAlgorithm(
                     digestAlgorithmOid, signatureAlgorithmOid);
             s = Signature.getInstance(jcaSignatureAlgorithm);
         } catch (SignatureException | NoSuchAlgorithmException e) {
-            e.printStackTrace();
-        }
-        if (s == null) {
             result.addError(Issue.V4_SIG_UNKNOWN_SIG_ALGORITHM);
             return;
         }
@@ -266,7 +257,7 @@
                 new HashMap<>();
         ApkSigningBlockUtils.computeChunkVerityTreeAndDigest(apkContent, actualContentDigests);
         if (result.signers.size() != 1) {
-            throw new RuntimeException("There should only be one signer for V4");
+            throw new IllegalStateException("There should only be one signer for V4");
         }
         final ApkSigningBlockUtils.Result.SignerInfo signerInfo = result.signers.get(0);
         for (ApkSigningBlockUtils.Result.SignerInfo.ContentDigest expected
diff --git a/src/main/java/com/android/apksig/internal/oid/OidConstants.java b/src/main/java/com/android/apksig/internal/oid/OidConstants.java
index 4504517..d80cbaa 100644
--- a/src/main/java/com/android/apksig/internal/oid/OidConstants.java
+++ b/src/main/java/com/android/apksig/internal/oid/OidConstants.java
@@ -458,4 +458,6 @@
         OID_TO_JCA_SIGNATURE_ALG.put(OID_SIG_SHA384_WITH_ECDSA, "SHA384withECDSA");
         OID_TO_JCA_SIGNATURE_ALG.put(OID_SIG_SHA512_WITH_ECDSA, "SHA512withECDSA");
     }
+
+    private OidConstants() {}
 }
diff --git a/src/main/java/com/android/apksig/internal/pkcs7/AlgorithmIdentifier.java b/src/main/java/com/android/apksig/internal/pkcs7/AlgorithmIdentifier.java
index 35a9f4b..c27c487 100644
--- a/src/main/java/com/android/apksig/internal/pkcs7/AlgorithmIdentifier.java
+++ b/src/main/java/com/android/apksig/internal/pkcs7/AlgorithmIdentifier.java
@@ -68,9 +68,8 @@
                 return new AlgorithmIdentifier(OID_DIGEST_SHA1, ASN1_DER_NULL);
             case SHA256:
                 return new AlgorithmIdentifier(OID_DIGEST_SHA256, ASN1_DER_NULL);
-            default:
-                throw new RuntimeException("Unsupported digest algorithm: " + digestAlgorithm);
         }
+        throw new IllegalArgumentException("Unsupported digest algorithm: " + digestAlgorithm);
     }
 
     /**
diff --git a/src/test/java/com/android/apksig/ApkSignerTest.java b/src/test/java/com/android/apksig/ApkSignerTest.java
index e4a22ee..f945234 100644
--- a/src/test/java/com/android/apksig/ApkSignerTest.java
+++ b/src/test/java/com/android/apksig/ApkSignerTest.java
@@ -16,6 +16,7 @@
 
 package com.android.apksig;
 
+import static com.android.apksig.apk.ApkUtils.SOURCE_STAMP_CERTIFICATE_HASH_ZIP_ENTRY_NAME;
 import static com.android.apksig.apk.ApkUtils.findZipSections;
 
 import static org.junit.Assert.assertArrayEquals;
@@ -765,7 +766,7 @@
                                 new ApkSigner.Builder(signers).setDebuggableApkPermitted(false)));
     }
 
-    @Test(expected = IllegalStateException.class)
+    @Test
     public void testV3SigningWithSignersNotInLineageFails() throws Exception {
         // APKs signed with the v3 scheme after a key rotation must specify the lineage containing
         // the proof of rotation. This test verifies that the signing will fail if the provided
@@ -776,7 +777,13 @@
                         getDefaultSignerConfigFromResources(SECOND_RSA_2048_SIGNER_RESOURCE_NAME));
         SigningCertificateLineage lineage =
                 Resources.toSigningCertificateLineage(getClass(), "rsa-1024-lineage-2-signers");
-        sign("original.apk", new ApkSigner.Builder(signers).setSigningCertificateLineage(lineage));
+        assertThrows(
+                IllegalStateException.class,
+                () ->
+                        sign(
+                                "original.apk",
+                                new ApkSigner.Builder(signers)
+                                        .setSigningCertificateLineage(lineage)));
     }
 
     @Test
@@ -863,7 +870,7 @@
                         .setSigningCertificateLineage(lineage));
     }
 
-    @Test(expected = IllegalStateException.class)
+    @Test
     public void testV3SigningWithMultipleSignersAndNoLineageFails() throws Exception {
         // The v3 signing scheme does not support multiple signers; if multiple signers are provided
         // it is assumed these signers are part of the lineage. This test verifies v3 signing
@@ -873,12 +880,15 @@
         ApkSigner.SignerConfig secondSigner =
                 getDefaultSignerConfigFromResources(SECOND_RSA_2048_SIGNER_RESOURCE_NAME);
         List<ApkSigner.SignerConfig> signers = Arrays.asList(firstSigner, secondSigner);
-        sign(
-                "original.apk",
-                new ApkSigner.Builder(signers)
-                        .setV1SigningEnabled(true)
-                        .setV2SigningEnabled(true)
-                        .setV3SigningEnabled(true));
+        assertThrows(
+                IllegalStateException.class,
+                () ->
+                        sign(
+                                "original.apk",
+                                new ApkSigner.Builder(signers)
+                                        .setV1SigningEnabled(true)
+                                        .setV2SigningEnabled(true)
+                                        .setV3SigningEnabled(true)));
     }
 
     @Test
@@ -986,14 +996,13 @@
         ApkUtils.ZipSections zipSections = findZipSections(signedApk);
         List<CentralDirectoryRecord> cdRecords =
                 V1SchemeVerifier.parseZipCentralDirectory(signedApk, zipSections);
-        CentralDirectoryRecord stampCdRecord =
-                cdRecords.stream()
-                        .filter(
-                                cdRecord ->
-                                        ApkUtils.SOURCE_STAMP_CERTIFICATE_HASH_ZIP_ENTRY_NAME.equals(
-                                                cdRecord.getName()))
-                        .findAny()
-                        .orElse(null);
+        CentralDirectoryRecord stampCdRecord = null;
+        for (CentralDirectoryRecord cdRecord : cdRecords) {
+            if (SOURCE_STAMP_CERTIFICATE_HASH_ZIP_ENTRY_NAME.equals(cdRecord.getName())) {
+                stampCdRecord = cdRecord;
+                break;
+            }
+        }
         assertNotNull(stampCdRecord);
         byte[] actualStampCertificateDigest =
                 LocalFileRecord.getUncompressedData(
@@ -1150,7 +1159,7 @@
         return Asn1BerParser.parse(subjectPublicKeyBuffer, RSAPublicKey.class);
     }
 
-    private SignatureInfo getSignatureInfoFromApk(
+    private static SignatureInfo getSignatureInfoFromApk(
             DataSource apk, int signatureVersionId, int signatureVersionBlockId)
             throws IOException, ZipFormatException,
                     ApkSigningBlockUtils.SignatureNotFoundException {
diff --git a/src/test/java/com/android/apksig/internal/util/FileChannelDataSourceTest.java b/src/test/java/com/android/apksig/internal/util/FileChannelDataSourceTest.java
index 9578926..12f08f1 100644
--- a/src/test/java/com/android/apksig/internal/util/FileChannelDataSourceTest.java
+++ b/src/test/java/com/android/apksig/internal/util/FileChannelDataSourceTest.java
@@ -90,14 +90,14 @@
         assertArrayEquals(expectedBytes, resultBytes);
     }
 
-    private byte[] getDataSinkBytes(ByteArrayDataSink dataSink) {
+    private static byte[] getDataSinkBytes(ByteArrayDataSink dataSink) {
         ByteBuffer result = dataSink.getByteBuffer(0, (int)dataSink.size());
         byte[] resultBytes = new byte[result.limit()];
         result.get(resultBytes);
         return resultBytes;
     }
 
-    private byte[] createFileContent(int fileSize) {
+    private static byte[] createFileContent(int fileSize) {
         byte[] fullFileContent = new byte[fileSize];
         for (int i = 0; i < fileSize; ++i) {
             fullFileContent[i] = (byte) (i % 255);