A Java wrapper around libarchive. NightCompress uses the Foreign Linker API available since JDK 22 to access native libraries.
NightCompress is released as a multi-release JAR:
- with Java < 22 as a no-op version that throws
UnsupportedOperationException
on any operation - with Java 22+ all the features are available
This lets you add the dependency in your project whatever the JDK used, and still enable the feature at runtime if the required JDK is used.
In order for the JAR to run properly, you will need to:
- Run Java 22 with the following options:
--enable-native-access=ALL-UNNAMED
- Make sure the path to the directory containing the native libraries is contained in the Java system
property
java.library.path
(check also this).- For Linux, normally it works fine when installed from a package manager. You can add the libraries' path to
the
LD_LIBRARY_PATH
environment variable. - For Mac, if using HomeBrew, you will need to set
JAVA_LIBRARY_PATH
to/usr/local/lib/
or/opt/homebrew/lib/
.
- For Linux, normally it works fine when installed from a package manager. You can add the libraries' path to
the
implementation "com.github.gotson.nightcompress:nightcompress:{version}"
implementation("com.github.gotson.nightcompress:nightcompress:{version}")
<dependency>
<groupId>com.github.gotson.nightcompress</groupId>
<artifactId>nightcompress</artifactId>
<version>{version}</version>
</dependency>
try {
if (Archive.isAvailable()) {
// do stuff
}
} catch(Exception e) {
// to be on the safe side
}
// Assuming you already have a Path pointing to the archive file and an OutputStream for writing to
Archive archive = new Archive(path);
while (archive.getNextEntry() !=null) {
try (InputStream is = archive.getInputStream()) {
is.transferTo(outputStream);
}
}
// Assuming you already know which entry you want to extract
try (InputStream is = Archive.getInputStream(path, entryName)) {
is.transferTo(outputStream);
}
NightCompress allows for some tuning using System Properties:
- Options for
Archive#getInputStream(Path)
:nightcompress.extractor.buffer-size
: accepts any positive integer. Defaults to32 * 1024
.- Sets the maximum size used for the dynamic byte buffer in the
PipedInputStream
.
- Sets the maximum size used for the dynamic byte buffer in the
nightcompress.extractor.use-executor
: accepts eithertrue
orfalse
. Defaults totrue
.- If
true
, it uses a cached thread pool for extracting the contents, which is generally faster. - If
false
, it will create a new thread on each call. This may be slower, but may require slightly less memory. - Options for tuning the thread pool:
nightcompress.extractor.max-threads
: accepts any positive integer. Defaults to2^31
.- Sets the maximum number of threads to be used in the pool. By default, there is no hard limit on the number of threads, but they are only created when needed, so the maximum should not exceed the number of threads calling this method at any given moment. Use this if you need to restrict the number of threads.
nightcompress.extractor.thread-keep-alive-seconds
: accepts any positive integer. Defaults to5
.- Sets the number of seconds a thread can be kept alive in the pool, waiting for a next extraction operation. After that time, the thread may be stopped.
- If
The panama
package bindings were generated using:
- jextract 22
- from the https://github.com/libarchive/libarchive/ repository, version 3.5.0
- based on a synthetic header file:
#include "archive.h" #include "archive_entry.h"