You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2025/08/02 21:13:07 UTC

(commons-compress) branch master updated: Add org.apache.commons.compress.archivers.ArchiveException.ArchiveException(String, Object...)

This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-compress.git


The following commit(s) were added to refs/heads/master by this push:
     new 16699b4c5 Add org.apache.commons.compress.archivers.ArchiveException.ArchiveException(String, Object...)
16699b4c5 is described below

commit 16699b4c5b5280cb6f078b0e2a91453052913791
Author: Gary D. Gregory <ga...@gmail.com>
AuthorDate: Sat Aug 2 17:13:01 2025 -0400

    Add org.apache.commons.compress.archivers.ArchiveException.ArchiveException(String,
    Object...)
---
 src/changes/changes.xml                                |  1 +
 .../org/apache/commons/compress/CompressException.java | 15 +++++++++++++++
 .../commons/compress/archivers/ArchiveEntry.java       |  2 +-
 .../commons/compress/archivers/ArchiveException.java   | 15 +++++++++++++++
 .../compress/archivers/ArchiveStreamFactory.java       |  4 ++--
 .../archivers/StreamingNotSupportedException.java      |  2 +-
 .../compress/archivers/ar/ArArchiveInputStream.java    |  2 +-
 .../compress/archivers/ar/ArArchiveOutputStream.java   |  6 +++---
 .../compress/archivers/arj/ArjArchiveInputStream.java  |  2 +-
 .../archivers/cpio/CpioArchiveInputStream.java         |  2 +-
 .../archivers/cpio/CpioArchiveOutputStream.java        |  4 ++--
 .../compress/archivers/dump/TapeInputStream.java       |  8 ++------
 .../commons/compress/archivers/examples/Archiver.java  |  2 +-
 .../commons/compress/archivers/examples/Expander.java  |  4 ++--
 .../compress/archivers/sevenz/AES256SHA256Decoder.java |  6 +++---
 .../commons/compress/archivers/sevenz/Coders.java      |  4 ++--
 .../commons/compress/archivers/sevenz/LZMADecoder.java |  2 +-
 .../commons/compress/archivers/sevenz/SevenZFile.java  | 18 +++++++++---------
 .../compress/archivers/tar/TarArchiveEntry.java        |  6 +++---
 .../compress/archivers/tar/TarArchiveOutputStream.java |  8 +++-----
 .../commons/compress/archivers/tar/TarUtils.java       | 15 ++++++++-------
 .../commons/compress/archivers/zip/BinaryTree.java     |  4 +---
 .../commons/compress/archivers/zip/BitStream.java      |  2 +-
 .../compress/archivers/zip/UnshrinkingInputStream.java |  4 ++--
 .../compress/archivers/zip/ZipArchiveInputStream.java  |  2 +-
 .../apache/commons/compress/archivers/zip/ZipFile.java | 11 ++++++-----
 .../commons/compress/archivers/zip/ZipIoUtil.java      |  6 ++++--
 .../compress/archivers/zip/ZipSplitOutputStream.java   |  4 ++--
 .../sevenz/SevenZAES256SHA256DecoderTest.java          |  2 +-
 29 files changed, 95 insertions(+), 68 deletions(-)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index dbd0cc9ba..ad230d287 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -61,6 +61,7 @@ The <action> type attribute can be add,update,fix,remove.
       <action type="fix" dev="ggregory" due-to="Gary Gregory">Classes in org.apache.commons.compress.compressors now throw a subclass of IOException called CompressorException instead of IOException when a formatting problem is found.</action>
       <!-- ADD -->
       <action type="add" dev="ggregory" due-to="Gary Gregory">Add org.apache.commons.compress.MemoryLimitException.MemoryLimitException(long, long).</action>
+      <action type="add" dev="ggregory" due-to="Gary Gregory">Add org.apache.commons.compress.archivers.ArchiveException.ArchiveException(String, Object...).</action>
       <!-- UPDATE -->
     </release>
     <release version="1.28.0" date="2025-07-26" description="This is a feature and maintenance release. Java 8 or later is required.">
diff --git a/src/main/java/org/apache/commons/compress/CompressException.java b/src/main/java/org/apache/commons/compress/CompressException.java
index 46d1db19c..170088c2b 100644
--- a/src/main/java/org/apache/commons/compress/CompressException.java
+++ b/src/main/java/org/apache/commons/compress/CompressException.java
@@ -72,6 +72,21 @@ public CompressException(final String message) {
         super(message);
     }
 
+    /**
+     * Constructs a new exception with the specified detail message format and arguments. The cause is not initialized.
+     * <p>
+     * The arguments are used with {@link String#format(String, Object...)}.
+     * </p>
+     *
+     * @param message The message format (which is saved for later retrieval by the {@link #getMessage()} method).
+     * @param args    the format arguments to use.
+     * @since 1.29.0
+     * @see String#format(String, Object...)
+     */
+    public CompressException(final String message, final Object... args) {
+        super(String.format(message, args));
+    }
+
     /**
      * Constructs a new exception with the specified detail message and cause.
      *
diff --git a/src/main/java/org/apache/commons/compress/archivers/ArchiveEntry.java b/src/main/java/org/apache/commons/compress/archivers/ArchiveEntry.java
index 5eda9f1bd..421f98869 100644
--- a/src/main/java/org/apache/commons/compress/archivers/ArchiveEntry.java
+++ b/src/main/java/org/apache/commons/compress/archivers/ArchiveEntry.java
@@ -76,7 +76,7 @@ default Path resolveIn(final Path parentPath) throws IOException {
         final String name = getName();
         final Path outputFile = parentPath.resolve(name).normalize();
         if (!outputFile.startsWith(parentPath)) {
-            throw new ArchiveException(String.format("Zip slip '%s' + '%s' -> '%s'", parentPath, name, outputFile));
+            throw new ArchiveException("Zip slip '%s' + '%s' -> '%s'", parentPath, name, outputFile);
         }
         return outputFile;
     }
diff --git a/src/main/java/org/apache/commons/compress/archivers/ArchiveException.java b/src/main/java/org/apache/commons/compress/archivers/ArchiveException.java
index 3258aac82..493735936 100644
--- a/src/main/java/org/apache/commons/compress/archivers/ArchiveException.java
+++ b/src/main/java/org/apache/commons/compress/archivers/ArchiveException.java
@@ -75,6 +75,21 @@ public ArchiveException(final String message, final Exception cause) {
         super(message, cause);
     }
 
+    /**
+     * Constructs a new exception with the specified detail message format and arguments. The cause is not initialized.
+     * <p>
+     * The arguments are used with {@link String#format(String, Object...)}.
+     * </p>
+     *
+     * @param message The message format (which is saved for later retrieval by the {@link #getMessage()} method).
+     * @param args    the format arguments to use.
+     * @since 1.29.0
+     * @see String#format(String, Object...)
+     */
+    public ArchiveException(final String message, final Object... args) {
+        super(message, args);
+    }
+
     /**
      * Constructs a new exception with the specified detail message and cause.
      *
diff --git a/src/main/java/org/apache/commons/compress/archivers/ArchiveStreamFactory.java b/src/main/java/org/apache/commons/compress/archivers/ArchiveStreamFactory.java
index e6bbba37d..b2f50bac1 100644
--- a/src/main/java/org/apache/commons/compress/archivers/ArchiveStreamFactory.java
+++ b/src/main/java/org/apache/commons/compress/archivers/ArchiveStreamFactory.java
@@ -474,7 +474,7 @@ public <I extends ArchiveInputStream<? extends ArchiveEntry>> I createArchiveInp
         if (archiveStreamProvider != null) {
             return archiveStreamProvider.createArchiveInputStream(archiverName, in, actualEncoding);
         }
-        throw new ArchiveException("Archiver: " + archiverName + " not found.");
+        throw new ArchiveException("Archiver: %s not found.", archiverName);
     }
 
     /**
@@ -538,7 +538,7 @@ public <O extends ArchiveOutputStream<? extends ArchiveEntry>> O createArchiveOu
         if (archiveStreamProvider != null) {
             return archiveStreamProvider.createArchiveOutputStream(archiverName, out, actualEncoding);
         }
-        throw new ArchiveException("Archiver: " + archiverName + " not found.");
+        throw new ArchiveException("Archiver: %s not found.", archiverName);
     }
 
     /**
diff --git a/src/main/java/org/apache/commons/compress/archivers/StreamingNotSupportedException.java b/src/main/java/org/apache/commons/compress/archivers/StreamingNotSupportedException.java
index 82fb2599b..23bd31aad 100644
--- a/src/main/java/org/apache/commons/compress/archivers/StreamingNotSupportedException.java
+++ b/src/main/java/org/apache/commons/compress/archivers/StreamingNotSupportedException.java
@@ -35,7 +35,7 @@ public class StreamingNotSupportedException extends ArchiveException {
      * @param format the format that has been requested/detected.
      */
     public StreamingNotSupportedException(final String format) {
-        super("The " + format + " doesn't support streaming.");
+        super("The %s doesn't support streaming.", format);
         this.format = format;
     }
 
diff --git a/src/main/java/org/apache/commons/compress/archivers/ar/ArArchiveInputStream.java b/src/main/java/org/apache/commons/compress/archivers/ar/ArArchiveInputStream.java
index 73b43b309..f44da0cf8 100644
--- a/src/main/java/org/apache/commons/compress/archivers/ar/ArArchiveInputStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/ar/ArArchiveInputStream.java
@@ -262,7 +262,7 @@ public ArArchiveEntry getNextArEntry() throws IOException {
             final int read = realized.length;
             trackReadBytes(read);
             if (read != expected.length) {
-                throw new ArchiveException("Failed to read header. Occurred at byte: " + getBytesRead());
+                throw new ArchiveException("Failed to read header. Occurred at byte: %,d", getBytesRead());
             }
             if (!Arrays.equals(expected, realized)) {
                 throw new ArchiveException("Invalid header " + ArchiveUtils.toAsciiString(realized));
diff --git a/src/main/java/org/apache/commons/compress/archivers/ar/ArArchiveOutputStream.java b/src/main/java/org/apache/commons/compress/archivers/ar/ArArchiveOutputStream.java
index 97e785442..edf356137 100644
--- a/src/main/java/org/apache/commons/compress/archivers/ar/ArArchiveOutputStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/ar/ArArchiveOutputStream.java
@@ -62,7 +62,7 @@ public ArArchiveOutputStream(final OutputStream out) {
 
     private String checkLength(final String value, final int max, final String name) throws IOException {
         if (value.length() > max) {
-            throw new ArchiveException(name + " too long");
+            throw new ArchiveException("'%s' too long", name);
         }
         return value;
     }
@@ -137,7 +137,7 @@ public void putArchiveEntry(final ArArchiveEntry entry) throws IOException {
             writeArchiveHeader();
         } else {
             if (prevEntry.getLength() != entryOffset) {
-                throw new ArchiveException("Length does not match entry (" + prevEntry.getLength() + " != " + entryOffset);
+                throw new ArchiveException("Length does not match entry (%,d != %,d", entryOffset, prevEntry.getLength());
             }
             if (prevEntryOpen) {
                 closeArchiveEntry();
@@ -181,7 +181,7 @@ private int writeEntryHeader(final ArArchiveEntry entry) throws IOException {
         final String eName = entry.getName();
         final int nLength = eName.length();
         if (LONGFILE_ERROR == longFileMode && nLength > 16) {
-            throw new ArchiveException("File name too long, > 16 chars: " + eName);
+            throw new ArchiveException("File name too long, > 16 chars: '%s'", eName);
         }
         if (LONGFILE_BSD == longFileMode && (nLength > 16 || eName.indexOf(SPACE) > -1)) {
             appendName = true;
diff --git a/src/main/java/org/apache/commons/compress/archivers/arj/ArjArchiveInputStream.java b/src/main/java/org/apache/commons/compress/archivers/arj/ArjArchiveInputStream.java
index 135e3ba51..497b023b0 100644
--- a/src/main/java/org/apache/commons/compress/archivers/arj/ArjArchiveInputStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/arj/ArjArchiveInputStream.java
@@ -172,7 +172,7 @@ public int read(final byte[] b, final int off, final int len) throws IOException
             throw new IllegalStateException("No current arj entry");
         }
         if (currentLocalFileHeader.method != LocalFileHeader.Methods.STORED) {
-            throw new ArchiveException("Unsupported compression method " + currentLocalFileHeader.method);
+            throw new ArchiveException("Unsupported compression method '%s'", currentLocalFileHeader.method);
         }
         return currentInputStream.read(b, off, len);
     }
diff --git a/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveInputStream.java b/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveInputStream.java
index ad854721b..2dc8ac8ee 100644
--- a/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveInputStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveInputStream.java
@@ -282,7 +282,7 @@ public CpioArchiveEntry getNextCPIOEntry() throws IOException {
                 this.entry = readOldAsciiEntry();
                 break;
             default:
-                throw new ArchiveException("Unknown magic [" + magicString + "]. Occurred at byte: " + getBytesRead());
+                throw new ArchiveException("Unknown magic '%s' at byte: %,d", magicString, getBytesRead());
             }
         }
 
diff --git a/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveOutputStream.java b/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveOutputStream.java
index 9b23fb340..7e3fb3a3f 100644
--- a/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveOutputStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveOutputStream.java
@@ -300,7 +300,7 @@ public void putArchiveEntry(final CpioArchiveEntry entry) throws IOException {
 
         final short format = entry.getFormat();
         if (format != this.entryFormat) {
-            throw new ArchiveException("Header format: " + format + " does not match existing format: " + this.entryFormat);
+            throw new ArchiveException("Header format: '%s' does not match existing format: '%s'", format, this.entryFormat);
         }
 
         if (this.names.put(entry.getName(), entry) != null) {
@@ -412,7 +412,7 @@ private void writeHeader(final CpioArchiveEntry e) throws IOException {
             writeOldBinaryEntry(e, swapHalfWord);
             break;
         default:
-            throw new ArchiveException("Unknown format " + e.getFormat());
+            throw new ArchiveException("Unknown format '%s'", e.getFormat());
         }
     }
 
diff --git a/src/main/java/org/apache/commons/compress/archivers/dump/TapeInputStream.java b/src/main/java/org/apache/commons/compress/archivers/dump/TapeInputStream.java
index 397491204..3b6eea704 100644
--- a/src/main/java/org/apache/commons/compress/archivers/dump/TapeInputStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/dump/TapeInputStream.java
@@ -290,23 +290,19 @@ public byte[] readRecord() throws IOException {
      */
     public void resetBlockSize(final int recsPerBlock, final boolean isCompressed) throws IOException {
         this.isCompressed = isCompressed;
-
         if (recsPerBlock < 1) {
-            throw new ArchiveException("Block with " + recsPerBlock + " records found, must be at least 1");
+            throw new ArchiveException("Block with %,d records found, must be at least 1", recsPerBlock);
         }
         blockSize = RECORD_SIZE * recsPerBlock;
         if (blockSize < 1) {
-            throw new ArchiveException("Block size cannot be less than or equal to 0: " + blockSize);
+            throw new ArchiveException("Block size cannot be less than or equal to 0: %,d", blockSize);
         }
-
         // save first block in case we need it again
         final byte[] oldBuffer = blockBuffer;
-
         // read rest of new block
         blockBuffer = new byte[blockSize];
         System.arraycopy(oldBuffer, 0, blockBuffer, 0, RECORD_SIZE);
         readFully(blockBuffer, RECORD_SIZE, blockSize - RECORD_SIZE);
-
         this.currBlkIdx = 0;
         this.readOffset = RECORD_SIZE;
     }
diff --git a/src/main/java/org/apache/commons/compress/archivers/examples/Archiver.java b/src/main/java/org/apache/commons/compress/archivers/examples/Archiver.java
index 6e5a9ef10..df06fa3cd 100644
--- a/src/main/java/org/apache/commons/compress/archivers/examples/Archiver.java
+++ b/src/main/java/org/apache/commons/compress/archivers/examples/Archiver.java
@@ -322,7 +322,7 @@ public void create(final String format, final SeekableByteChannel target, final
                 create(c.track(new SevenZOutputFile(target)), directory);
             } else {
                 // never reached as prefersSeekableByteChannel only returns true for ZIP and 7z
-                throw new ArchiveException("Don't know how to handle format " + format);
+                throw new ArchiveException("Don't know how to handle format '%s'", format);
             }
         }
     }
diff --git a/src/main/java/org/apache/commons/compress/archivers/examples/Expander.java b/src/main/java/org/apache/commons/compress/archivers/examples/Expander.java
index 0acf2a914..e2a1b87c8 100644
--- a/src/main/java/org/apache/commons/compress/archivers/examples/Expander.java
+++ b/src/main/java/org/apache/commons/compress/archivers/examples/Expander.java
@@ -73,7 +73,7 @@ private <T extends ArchiveEntry> void expand(final ArchiveEntrySupplier<T> suppl
             final Path targetPath = nullTarget ? null : nextEntry.resolveIn(targetDirPath);
             if (nextEntry.isDirectory()) {
                 if (!nullTarget && !Files.isDirectory(targetPath) && Files.createDirectories(targetPath) == null) {
-                    throw new ArchiveException("Failed to create directory " + targetPath);
+                    throw new ArchiveException("Failed to create directory '%s'", targetPath);
                 }
             } else {
                 final Path parent = nullTarget ? null : targetPath.getParent();
@@ -402,7 +402,7 @@ public void expand(final String format, final SeekableByteChannel archive, final
                 expand(c.track(SevenZFile.builder().setSeekableByteChannel(archive).get()), targetDirectory);
             } else {
                 // never reached as prefersSeekableByteChannel only returns true for TAR, ZIP and 7z
-                throw new ArchiveException("Don't know how to handle format " + format);
+                throw new ArchiveException("Don't know how to handle format '%s'", format);
             }
         }
     }
diff --git a/src/main/java/org/apache/commons/compress/archivers/sevenz/AES256SHA256Decoder.java b/src/main/java/org/apache/commons/compress/archivers/sevenz/AES256SHA256Decoder.java
index 69a90f372..f84f78c90 100644
--- a/src/main/java/org/apache/commons/compress/archivers/sevenz/AES256SHA256Decoder.java
+++ b/src/main/java/org/apache/commons/compress/archivers/sevenz/AES256SHA256Decoder.java
@@ -68,10 +68,10 @@ private CipherInputStream init() throws IOException {
                 return cipherInputStream;
             }
             if (coder.properties == null) {
-                throw new ArchiveException("Missing AES256 properties in " + archiveName);
+                throw new ArchiveException("Missing AES256 properties in '%s'", archiveName);
             }
             if (coder.properties.length < 2) {
-                throw new ArchiveException("AES256 properties too short in " + archiveName);
+                throw new ArchiveException("AES256 properties too short in '%s'", archiveName);
             }
             final int byte0 = 0xff & coder.properties[0];
             final int numCyclesPower = byte0 & 0x3f;
@@ -79,7 +79,7 @@ private CipherInputStream init() throws IOException {
             final int ivSize = (byte0 >> 6 & 1) + (byte1 & 0x0f);
             final int saltSize = (byte0 >> 7 & 1) + (byte1 >> 4);
             if (2 + saltSize + ivSize > coder.properties.length) {
-                throw new ArchiveException("Salt size + IV size too long in " + archiveName);
+                throw new ArchiveException("Salt size + IV size too long in '%s'", archiveName);
             }
             final byte[] salt = new byte[saltSize];
             System.arraycopy(coder.properties, 2, salt, 0, saltSize);
diff --git a/src/main/java/org/apache/commons/compress/archivers/sevenz/Coders.java b/src/main/java/org/apache/commons/compress/archivers/sevenz/Coders.java
index 6a8d39b0e..a30012a06 100644
--- a/src/main/java/org/apache/commons/compress/archivers/sevenz/Coders.java
+++ b/src/main/java/org/apache/commons/compress/archivers/sevenz/Coders.java
@@ -228,7 +228,7 @@ static InputStream addDecoder(final String archiveName, final InputStream is, fi
             final int maxMemoryLimitKiB) throws IOException {
         final AbstractCoder cb = findByMethod(SevenZMethod.byId(coder.decompressionMethodId));
         if (cb == null) {
-            throw new ArchiveException("Unsupported compression method " + Arrays.toString(coder.decompressionMethodId) + " used in " + archiveName);
+            throw new ArchiveException("Unsupported compression method %s used in '%s'", Arrays.toString(coder.decompressionMethodId), archiveName);
         }
         return cb.decode(archiveName, is, uncompressedLength, coder, password, maxMemoryLimitKiB);
     }
@@ -236,7 +236,7 @@ static InputStream addDecoder(final String archiveName, final InputStream is, fi
     static OutputStream addEncoder(final OutputStream out, final SevenZMethod method, final Object options) throws IOException {
         final AbstractCoder cb = findByMethod(method);
         if (cb == null) {
-            throw new ArchiveException("Unsupported compression method " + method);
+            throw new ArchiveException("Unsupported compression method '%s'", method);
         }
         return cb.encode(out, options);
     }
diff --git a/src/main/java/org/apache/commons/compress/archivers/sevenz/LZMADecoder.java b/src/main/java/org/apache/commons/compress/archivers/sevenz/LZMADecoder.java
index fc8e143e2..6d7ab1a6a 100644
--- a/src/main/java/org/apache/commons/compress/archivers/sevenz/LZMADecoder.java
+++ b/src/main/java/org/apache/commons/compress/archivers/sevenz/LZMADecoder.java
@@ -48,7 +48,7 @@ InputStream decode(final String archiveName, final InputStream in, final long un
         final byte propsByte = coder.properties[0];
         final int dictSize = getDictionarySize(coder);
         if (dictSize > LZMAInputStream.DICT_SIZE_MAX) {
-            throw new ArchiveException("Dictionary larger than 4 GiB maximum size used in " + archiveName);
+            throw new ArchiveException("Dictionary larger than 4 GiB maximum size used in '%s'", archiveName);
         }
         final int memoryUsageInKiB = LZMAInputStream.getMemoryUsage(dictSize, propsByte);
         if (memoryUsageInKiB > maxMemoryLimitKiB) {
diff --git a/src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZFile.java b/src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZFile.java
index 664a31846..342a213bb 100644
--- a/src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZFile.java
+++ b/src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZFile.java
@@ -354,7 +354,7 @@ public Builder setUseDefaultNameForUnnamedEntries(final boolean useDefaultNameFo
      */
     private static int assertFitsIntoNonNegativeInt(final String description, final long value) throws IOException {
         if (value > Integer.MAX_VALUE || value < 0) {
-            throw new ArchiveException(String.format("Cannot handle %s %,d", description, value));
+            throw new ArchiveException("Cannot handle %s %,d", description, value);
         }
         return (int) value;
     }
@@ -1548,7 +1548,7 @@ private Archive readHeaders(final byte[] password) throws IOException {
         final byte archiveVersionMajor = buf.get();
         final byte archiveVersionMinor = buf.get();
         if (archiveVersionMajor != 0) {
-            throw new ArchiveException(String.format("Unsupported 7z version (%d,%d)", archiveVersionMajor, archiveVersionMinor));
+            throw new ArchiveException("Unsupported 7z version (%d,%d)", archiveVersionMajor, archiveVersionMinor);
         }
         boolean headerLooksValid = false; // See https://www.7-zip.org/recover.html - "There is no correct End Header at the end of archive"
         final long startHeaderCrc = 0xffffFFFFL & buf.getInt();
@@ -1789,7 +1789,7 @@ private ArchiveStatistics sanityCheckAndCollectStatistics(final ByteBuffer heade
             nid = getUnsignedByte(header);
         }
         if (nid != NID.kEnd) {
-            throw new ArchiveException("Badly terminated header, found " + nid);
+            throw new ArchiveException("Badly terminated header, found %s", nid);
         }
         return stats;
     }
@@ -1850,7 +1850,7 @@ private void sanityCheckFilesInfo(final ByteBuffer header, final ArchiveStatisti
                     }
                 }
                 if (filesSeen != stats.numberOfEntries) {
-                    throw new ArchiveException("Invalid number of file names (" + filesSeen + " instead of " + stats.numberOfEntries + ")");
+                    throw new ArchiveException("Invalid number of file names (%,d instead of %,d)", filesSeen, stats.numberOfEntries);
                 }
                 break;
             }
@@ -1995,7 +1995,7 @@ private int sanityCheckFolder(final ByteBuffer header, final ArchiveStatistics s
     private void sanityCheckPackInfo(final ByteBuffer header, final ArchiveStatistics stats) throws IOException {
         final long packPos = readUint64(header);
         if (packPos < 0 || SIGNATURE_HEADER_SIZE + packPos > channel.size() || SIGNATURE_HEADER_SIZE + packPos < 0) {
-            throw new ArchiveException("packPos (" + packPos + ") is out of range");
+            throw new ArchiveException("packPos (%,d) is out of range", packPos);
         }
         final long numPackStreams = readUint64(header);
         stats.numberOfPackedStreams = assertFitsIntoNonNegativeInt("numPackStreams", numPackStreams);
@@ -2007,7 +2007,7 @@ private void sanityCheckPackInfo(final ByteBuffer header, final ArchiveStatistic
                 totalPackSizes = Math.addExact(totalPackSizes, packSize);
                 final long endOfPackStreams = SIGNATURE_HEADER_SIZE + packPos + totalPackSizes;
                 if (packSize < 0 || endOfPackStreams > channel.size() || endOfPackStreams < packPos) {
-                    throw new ArchiveException("packSize (" + packSize + ") is out of range");
+                    throw new ArchiveException("packSize (%,d) is out of range", packSize);
                 }
             }
             nid = getUnsignedByte(header);
@@ -2020,7 +2020,7 @@ private void sanityCheckPackInfo(final ByteBuffer header, final ArchiveStatistic
             nid = getUnsignedByte(header);
         }
         if (nid != NID.kEnd) {
-            throw new ArchiveException("Badly terminated PackInfo (" + nid + ")");
+            throw new ArchiveException("Badly terminated PackInfo (%s)", nid);
         }
     }
 
@@ -2097,7 +2097,7 @@ private void sanityCheckSubStreamsInfo(final ByteBuffer header, final ArchiveSta
     private void sanityCheckUnpackInfo(final ByteBuffer header, final ArchiveStatistics stats) throws IOException {
         int nid = getUnsignedByte(header);
         if (nid != NID.kFolder) {
-            throw new ArchiveException("Expected kFolder, got " + nid);
+            throw new ArchiveException("Expected NID.kFolder, got %s", nid);
         }
         final long numFolders = readUint64(header);
         stats.numberOfFolders = assertFitsIntoNonNegativeInt("numFolders", numFolders);
@@ -2116,7 +2116,7 @@ private void sanityCheckUnpackInfo(final ByteBuffer header, final ArchiveStatist
         }
         nid = getUnsignedByte(header);
         if (nid != NID.kCodersUnpackSize) {
-            throw new ArchiveException("Expected kCodersUnpackSize, got " + nid);
+            throw new ArchiveException("Expected kCodersUnpackSize, got %s", nid);
         }
         for (final int numberOfOutputStreams : numberOfOutputStreamsPerFolder) {
             for (int i = 0; i < numberOfOutputStreams; i++) {
diff --git a/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveEntry.java b/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveEntry.java
index 7497a320a..be93580fe 100644
--- a/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveEntry.java
+++ b/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveEntry.java
@@ -268,7 +268,7 @@ private static String normalizeFileName(String fileName, final boolean preserveA
     private static Instant parseInstantFromDecimalSeconds(final String value) throws IOException {
         // Validate field values to prevent denial of service attacks with BigDecimal values (see JDK-6560193)
         if (!PAX_EXTENDED_HEADER_FILE_TIMES_PATTERN.matcher(value).matches()) {
-            throw new ArchiveException("Corrupted PAX header. Time field value is invalid '" + value + "'");
+            throw new ArchiveException("Corrupted PAX header. Time field value is invalid '%s'", value);
         }
 
         final BigDecimal epochSeconds = new BigDecimal(value);
@@ -1000,11 +1000,11 @@ public List<TarArchiveStructSparse> getOrderedSparseHeaders() throws IOException
         for (int i = 0; i < numberOfHeaders; i++) {
             final TarArchiveStructSparse str = orderedAndFiltered.get(i);
             if (i + 1 < numberOfHeaders && str.getOffset() + str.getNumbytes() > orderedAndFiltered.get(i + 1).getOffset()) {
-                throw new ArchiveException("Corrupted TAR archive. Sparse blocks for " + getName() + " overlap each other.");
+                throw new ArchiveException("Corrupted TAR archive. Sparse blocks for '%s' overlap each other.", getName());
             }
             if (str.getOffset() + str.getNumbytes() < 0) {
                 // integer overflow?
-                throw new ArchiveException("Unreadable TAR archive. Offset and numbytes for sparse block in " + getName() + " too large.");
+                throw new ArchiveException("Unreadable TAR archive. Offset and numbytes for sparse block in '%s' too large.", getName());
             }
         }
         if (!orderedAndFiltered.isEmpty()) {
diff --git a/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveOutputStream.java b/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveOutputStream.java
index 9cb6aacc3..bfaf7e89d 100644
--- a/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveOutputStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveOutputStream.java
@@ -314,8 +314,7 @@ public void closeArchiveEntry() throws IOException {
         }
         ((FixedLengthBlockOutputStream) out).flushBlock();
         if (currBytes < currSize) {
-            throw new ArchiveException(
-                    "Entry '" + currName + "' closed at '" + currBytes + "' before the '" + currSize + "' bytes specified in the header were written");
+            throw new ArchiveException("Entry '%s' closed at %,d before the %,d bytes specified in the header were written", currName, currBytes, currSize);
         }
         recordsWritten += currSize / RECORD_SIZE;
 
@@ -636,8 +635,7 @@ public void write(final byte[] wBuf, final int wOffset, final int numToWrite) th
             throw new IllegalStateException("No current tar entry");
         }
         if (currBytes + numToWrite > currSize) {
-            throw new ArchiveException(
-                    "Request to write '" + numToWrite + "' bytes exceeds size in header of '" + currSize + "' bytes for entry '" + currName + "'");
+            throw new ArchiveException("Request to write %,d bytes exceeds size in header of %,d bytes for entry '%s'", numToWrite, currSize, currName);
         }
         out.write(wBuf, wOffset, numToWrite);
         currBytes += numToWrite;
@@ -678,7 +676,7 @@ void writePaxHeaders(final TarArchiveEntry entry, final String entryName, final
      */
     private void writeRecord(final byte[] record) throws IOException {
         if (record.length != RECORD_SIZE) {
-            throw new ArchiveException("Record to write has length '" + record.length + "' which is not the record size of '" + RECORD_SIZE + "'");
+            throw new ArchiveException("Record to write has length %,d which is not the record size of %,d", record.length, RECORD_SIZE);
         }
 
         out.write(record);
diff --git a/src/main/java/org/apache/commons/compress/archivers/tar/TarUtils.java b/src/main/java/org/apache/commons/compress/archivers/tar/TarUtils.java
index b65ac80cd..4a99b283e 100644
--- a/src/main/java/org/apache/commons/compress/archivers/tar/TarUtils.java
+++ b/src/main/java/org/apache/commons/compress/archivers/tar/TarUtils.java
@@ -666,12 +666,12 @@ protected static Map<String, String> parsePaxHeaders(final InputStream inputStre
                             if (restLen <= 1) { // only NL
                                 headers.remove(keyword);
                             } else if (headerSize >= 0 && restLen > headerSize - totalRead) {
-                                throw new ArchiveException("Paxheader value size " + restLen + " exceeds size of header record");
+                                throw new ArchiveException("Paxheader value size %,d exceeds size of header record", restLen);
                             } else {
                                 final byte[] rest = IOUtils.readRange(inputStream, restLen);
                                 final int got = rest.length;
                                 if (got != restLen) {
-                                    throw new ArchiveException("Failed to read Paxheader. Expected " + restLen + " bytes, read " + got);
+                                    throw new ArchiveException("Failed to read Paxheader. Expected %,d bytes, read %,d", restLen, got);
                                 }
                                 totalRead += restLen;
                                 // Drop trailing NL
@@ -690,22 +690,23 @@ protected static Map<String, String> parsePaxHeaders(final InputStream inputStre
                                     try {
                                         offset = Long.valueOf(value);
                                     } catch (final NumberFormatException ex) {
-                                        throw new ArchiveException("Failed to read Paxheader." + TarGnuSparseKeys.OFFSET + " contains a non-numeric value");
+                                        throw new ArchiveException("Failed to read Paxheader. Offset %s contains a non-numeric value",
+                                                TarGnuSparseKeys.OFFSET);
                                     }
                                     if (offset < 0) {
-                                        throw new ArchiveException("Failed to read Paxheader." + TarGnuSparseKeys.OFFSET + " contains negative value");
+                                        throw new ArchiveException("Failed to read Paxheader. Offset %s contains negative value", TarGnuSparseKeys.OFFSET);
                                     }
                                 }
 
                                 // for 0.0 PAX Headers
                                 if (keyword.equals(TarGnuSparseKeys.NUMBYTES)) {
                                     if (offset == null) {
-                                        throw new ArchiveException(
-                                                "Failed to read Paxheader." + TarGnuSparseKeys.OFFSET + " is expected before GNU.sparse.numbytes shows up.");
+                                        throw new ArchiveException("Failed to read Paxheader. %s is expected before GNU.sparse.numbytes shows up.",
+                                                TarGnuSparseKeys.OFFSET);
                                     }
                                     final long numbytes = ParsingUtils.parseLongValue(value);
                                     if (numbytes < 0) {
-                                        throw new ArchiveException("Failed to read Paxheader." + TarGnuSparseKeys.NUMBYTES + " contains negative value");
+                                        throw new ArchiveException("Failed to read Paxheader. %s contains negative value", TarGnuSparseKeys.NUMBYTES);
                                     }
                                     sparseHeaders.add(new TarArchiveStructSparse(offset, numbytes));
                                     offset = null;
diff --git a/src/main/java/org/apache/commons/compress/archivers/zip/BinaryTree.java b/src/main/java/org/apache/commons/compress/archivers/zip/BinaryTree.java
index 06123a8a6..0df1cebd1 100644
--- a/src/main/java/org/apache/commons/compress/archivers/zip/BinaryTree.java
+++ b/src/main/java/org/apache/commons/compress/archivers/zip/BinaryTree.java
@@ -178,13 +178,11 @@ public void addLeaf(final int node, final int path, final int depth, final int v
      */
     public int read(final BitStream stream) throws IOException {
         int currentIndex = 0;
-
         while (true) {
             final int bit = stream.readBit();
             if (bit == -1) {
                 return -1;
             }
-
             final int childIndex = 2 * currentIndex + 1 + bit;
             final int value = tree[childIndex];
             if (value == NODE) {
@@ -193,7 +191,7 @@ public int read(final BitStream stream) throws IOException {
             } else if (value != UNDEFINED) {
                 return value;
             } else {
-                throw new ArchiveException("The child " + bit + " of node at index " + currentIndex + " is not defined");
+                throw new ArchiveException("The child %,d of node at index %,d is not defined", bit, currentIndex);
             }
         }
     }
diff --git a/src/main/java/org/apache/commons/compress/archivers/zip/BitStream.java b/src/main/java/org/apache/commons/compress/archivers/zip/BitStream.java
index 74d27052c..6c7ccf7cf 100644
--- a/src/main/java/org/apache/commons/compress/archivers/zip/BitStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/zip/BitStream.java
@@ -46,7 +46,7 @@ final class BitStream extends BitInputStream {
      */
     long nextBits(final int n) throws IOException {
         if (n < 0 || n > 8) {
-            throw new ArchiveException("Trying to read " + n + " bits, at most 8 are allowed");
+            throw new ArchiveException("Trying to read %,d bits, at most 8 are allowed", n);
         }
         return readBits(n);
     }
diff --git a/src/main/java/org/apache/commons/compress/archivers/zip/UnshrinkingInputStream.java b/src/main/java/org/apache/commons/compress/archivers/zip/UnshrinkingInputStream.java
index 03b90119b..b55eb7d05 100644
--- a/src/main/java/org/apache/commons/compress/archivers/zip/UnshrinkingInputStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/zip/UnshrinkingInputStream.java
@@ -95,7 +95,7 @@ protected int decompressNextSymbol() throws IOException {
         }
         final int subCode = readNextCode();
         if (subCode < 0) {
-            throw new ArchiveException("Unexpected EOF;");
+            throw new ArchiveException("Unexpected EOF");
         }
         if (subCode == 1) {
             if (getCodeSize() >= MAX_CODE_SIZE) {
@@ -106,7 +106,7 @@ protected int decompressNextSymbol() throws IOException {
             partialClear();
             setTableSize(getClearCode() + 1);
         } else {
-            throw new ArchiveException("Invalid clear code subcode " + subCode);
+            throw new ArchiveException("Invalid clear code subcode %s", subCode);
         }
         return 0;
     }
diff --git a/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java b/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java
index c1557ca3f..67dd00aa3 100644
--- a/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java
@@ -913,7 +913,7 @@ private void processZip64Extra(final ZipLong size, final ZipLong cSize) throws Z
     private void pushback(final byte[] buf, final int offset, final int length) throws IOException {
         if (offset < 0) {
             // Instead of ArrayIndexOutOfBoundsException
-            throw new ArchiveException(String.format("Negative offset %,d into buffer", offset));
+            throw new ArchiveException("Negative offset %,d into buffer", offset);
         }
         ((PushbackInputStream) in).unread(buf, offset, length);
         pushedBackBytes(length);
diff --git a/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java b/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java
index 43253aa20..70a3819b7 100644
--- a/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java
+++ b/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java
@@ -543,7 +543,8 @@ private static SeekableByteChannel openZipChannel(final Path path, final long ma
                 numberOfDisks = (buf.getShort() & 0xffff) + 1;
             }
             if (numberOfDisks > Math.min(maxNumberOfDisks, Integer.MAX_VALUE)) {
-                throw new ArchiveException("Too many disks for zip archive, max=" + Math.min(maxNumberOfDisks, Integer.MAX_VALUE) + " actual=" + numberOfDisks);
+                throw new ArchiveException("Too many disks for zip archive, max = %,d actual = %,d", Math.min(maxNumberOfDisks, Integer.MAX_VALUE),
+                        numberOfDisks);
             }
 
             if (numberOfDisks <= 1) {
@@ -1626,13 +1627,13 @@ private void sanityCheckLFHOffset(final ZipArchiveEntry entry) throws IOExceptio
         }
         if (isSplitZipArchive) {
             if (entry.getDiskNumberStart() > centralDirectoryStartDiskNumber) {
-                throw new ArchiveException("Local file header for " + entry.getName() + " starts on a later disk than central directory");
+                throw new ArchiveException("Local file header for '%s' starts on a later disk than central directory", entry.getName());
             }
             if (entry.getDiskNumberStart() == centralDirectoryStartDiskNumber && entry.getLocalHeaderOffset() > centralDirectoryStartRelativeOffset) {
-                throw new ArchiveException("Local file header for " + entry.getName() + " starts after central directory");
+                throw new ArchiveException("Local file header for '%s' starts after central directory", entry.getName());
             }
         } else if (entry.getLocalHeaderOffset() > centralDirectoryStartOffset) {
-            throw new ArchiveException("Local file header for " + entry.getName() + " starts after central directory");
+            throw new ArchiveException("Local file header for '%s' starts after central directory", entry.getName());
         }
     }
 
@@ -1654,7 +1655,7 @@ private int[] setDataOffset(final ZipArchiveEntry entry) throws IOException {
         final int extraFieldLen = ZipShort.getValue(shortBuf);
         entry.setDataOffset(offset + LFH_OFFSET_FOR_FILENAME_LENGTH + ZipConstants.SHORT + ZipConstants.SHORT + fileNameLen + extraFieldLen);
         if (entry.getDataOffset() + entry.getCompressedSize() > centralDirectoryStartOffset) {
-            throw new ArchiveException("Data for " + entry.getName() + " overlaps with central directory.");
+            throw new ArchiveException("Data for '%s' overlaps with central directory.", entry.getName());
         }
         return new int[] { fileNameLen, extraFieldLen };
     }
diff --git a/src/main/java/org/apache/commons/compress/archivers/zip/ZipIoUtil.java b/src/main/java/org/apache/commons/compress/archivers/zip/ZipIoUtil.java
index b2149a6a1..38bc9464b 100644
--- a/src/main/java/org/apache/commons/compress/archivers/zip/ZipIoUtil.java
+++ b/src/main/java/org/apache/commons/compress/archivers/zip/ZipIoUtil.java
@@ -50,7 +50,8 @@ static void writeAll(final FileChannel channel, final ByteBuffer buffer, final l
                 continue;
             }
             if (written < 0) {
-                throw new ArchiveException("Failed to write all bytes in the buffer for channel=" + channel + ", length=" + remaining + ", written=" + written);
+                throw new ArchiveException("Failed to write all bytes in the buffer for channel = %s, length = %,d, written = %,d", channel, remaining,
+                        written);
             }
             currentPos += written;
         }
@@ -73,7 +74,8 @@ static void writeAll(final WritableByteChannel channel, final ByteBuffer buffer)
                 continue;
             }
             if (written < 0) {
-                throw new ArchiveException("Failed to write all bytes in the buffer for channel=" + channel + ", length=" + remaining + ", written=" + written);
+                throw new ArchiveException("Failed to write all bytes in the buffer for channel = %s, length = %,d, written = %,d", channel, remaining,
+                        written);
             }
         }
     }
diff --git a/src/main/java/org/apache/commons/compress/archivers/zip/ZipSplitOutputStream.java b/src/main/java/org/apache/commons/compress/archivers/zip/ZipSplitOutputStream.java
index 1bbde437c..4603cc117 100644
--- a/src/main/java/org/apache/commons/compress/archivers/zip/ZipSplitOutputStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/zip/ZipSplitOutputStream.java
@@ -105,7 +105,7 @@ final class ZipSplitOutputStream extends RandomAccessOutputStream {
 
     public long calculateDiskPosition(final long disk, final long localOffset) throws IOException {
         if (disk >= Integer.MAX_VALUE) {
-            throw new ArchiveException("Disk number exceeded internal limits: limit=" + Integer.MAX_VALUE + " requested=" + disk);
+            throw new ArchiveException("Disk number exceeded internal limits: limit = %,d requested = %,d", Integer.MAX_VALUE, disk);
         }
         return diskToPosition.get((int) disk) + localOffset;
     }
@@ -139,7 +139,7 @@ private Path createNewSplitSegmentFile(final Integer zipSplitSegmentSuffixIndex)
         final Path newFile = getSplitSegmentFileName(zipSplitSegmentSuffixIndex);
 
         if (Files.exists(newFile)) {
-            throw new ArchiveException("Split ZIP segment " + newFile + " already exists");
+            throw new ArchiveException("Split ZIP segment '%s' already exists", newFile);
         }
         return newFile;
     }
diff --git a/src/test/java/org/apache/commons/compress/archivers/sevenz/SevenZAES256SHA256DecoderTest.java b/src/test/java/org/apache/commons/compress/archivers/sevenz/SevenZAES256SHA256DecoderTest.java
index d49900f11..e9f9a0d68 100644
--- a/src/test/java/org/apache/commons/compress/archivers/sevenz/SevenZAES256SHA256DecoderTest.java
+++ b/src/test/java/org/apache/commons/compress/archivers/sevenz/SevenZAES256SHA256DecoderTest.java
@@ -46,7 +46,7 @@ void testDecodeWithNonEmptyString() throws IOException {
             final Coder coder = new Coder(null, 0, 0, byteArray);
             try (InputStream inputStream = aES256SHA256Decoder.decode("x", bufferedInputStream, 3138, coder, coder.properties, Integer.MAX_VALUE)) {
                 final IOException e = assertThrows(ArchiveException.class, () -> new ObjectInputStream(inputStream), "Expecting exception: IOException");
-                assertEquals("Salt size + IV size too long in x", e.getMessage());
+                assertEquals("Salt size + IV size too long in 'x'", e.getMessage());
                 assertEquals("org.apache.commons.compress.archivers.sevenz.AES256SHA256Decoder$AES256SHA256DecoderInputStream",
                         e.getStackTrace()[0].getClassName());
             }