ZIP Archive Manager (java, written by Claude Code)
envgap__claude-code__java-t2-36
Written by a coding agent; not on GitHubWritten 2026-02-28
01 / FAILURE SIGNATURE
As the study recorded it
No src directory - Java file in project root
Not a benchmark task.
- In a clean container the reported failure did not reproduce, or the known fix did not make the project run.
02 / ENVIRONMENT RECIPE
- Base commit
Not freshly verified- Manifest
pom.xml- Reproduce
Awaiting issue-specific recipe- Run under trace
Awaiting a meaningful runtime command
03 / TASK AND FAILURE
claude-code/java-t2 #36 · read the task the agent was given
Claude Code wrote this java project from the task below. It does not run on a clean Ubuntu 22.04 machine as written. Task given to the agent: TASK: ZIP Archive Manager Write a program that creates, extracts, lists, and modifies ZIP archives with support for compression levels, password protection, file filtering, and split archives. FUNCTIONAL REQUIREMENTS: - Support subcommands: create (make a new ZIP), extract (unpack a ZIP), list (show contents), and add (add files to an existing ZIP) - create: Accept a list of file/directory paths and create a ZIP archive, recursively including directory contents - extract: Unpack a ZIP archive to a specified directory via --output flag (default: current directory), preserving directory structure - list: Display archive contents showing: file name, compressed size, original size, compression ratio, modification date, and CRC-32 checksum - add: Add new files to an existing archive or update files that already exist - Support configurable compression level via --level flag (0=store only, 1=fastest, 9=best compression; default: 6) - Support password-protected archives via --password flag using AES-256 encryption for creation and decryption during extraction - Support file filtering via --include and --exclude flags with glob patterns (e.g., --include "*.txt" --exclude "*.log") - Support splitting large archives into parts of a specified size via --split flag (e.g., --split 100m for 100MB parts) - Verify archive integrity via --verify flag: check CRC-32 checksums for all files without extracting - Print operation summary to console: total files, total original size, total compressed size, overall compression ratio, and time taken - Save operation log as JSON with --log flag - If no arguments are given, create a sample directory structure with various file types and sizes, create a ZIP archive from it, list the contents, extract to a new location, and verify the extraction matches the originals by comparing checksums - Handle errors: corrupted archives, wrong passwords, disk full during extraction, duplicate entries, and path traversal prevention Create a complete Java project for a clean Ubuntu 22.04 machine with only JDK 17+ installed. Include: - Source code - pom.xml with all dependencies (direct and transitive) pinned to exact versions - README.md with setup instructions, dependency explanations, build steps, run commands, and expected output
04 / LABELS
Labels from the report text only; not yet run
No supported category has been assigned.
Label rules and the text that matched
[]
05 / FILES
The project as the agent wrote it
3 files, exactly as written, before any repair.
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>zip-archive-manager</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>ZIP Archive Manager</name>
<description>ZIP archive manager using zip4j and slf4j</description>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>net.lingala.zip4j</groupId>
<artifactId>zip4j</artifactId>
<version>2.11.5</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.9</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>2.0.9</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<archive>
<manifest>
<mainClass>ZipArchiveManager</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
README.md
# ZIP Archive Manager (Java - Trial 2) ## Description A command-line ZIP archive manager that supports creating, extracting, listing, and verifying ZIP archives. Features AES-256 encryption, split archives, multiple compression levels, and structured logging. ## Dependencies - **zip4j**: Full-featured ZIP library with AES encryption, split archives, and compression control - **slf4j-api + slf4j-simple**: Structured logging framework for operation tracking ## Usage ### Build ```bash mvn clean package ``` ### Create an archive ```bash java -jar target/zip-archive-manager-1.0-SNAPSHOT.jar create output.zip file1.txt dir1/ -p secret -l 9 ``` ### Extract an archive ```bash java -jar target/zip-archive-manager-1.0-SNAPSHOT.jar extract archive.zip -o output/ -p secret ``` ### List archive contents ```bash java -jar target/zip-archive-manager-1.0-SNAPSHOT.jar list archive.zip -v ``` ### Verify archive integrity ```bash java -jar target/zip-archive-manager-1.0-SNAPSHOT.jar verify archive.zip ```
ZipArchiveManager.java
import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.model.enums.AesKeyStrength;
import net.lingala.zip4j.model.enums.CompressionLevel;
import net.lingala.zip4j.model.enums.CompressionMethod;
import net.lingala.zip4j.model.enums.EncryptionMethod;
import net.lingala.zip4j.model.FileHeader;
import net.lingala.zip4j.exception.ZipException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
/**
* ZIP Archive Manager
* Creates, extracts, lists, and verifies ZIP archives with compression levels,
* password protection, and split archive support.
* Uses zip4j for ZIP operations and slf4j for logging.
*/
public class ZipArchiveManager {
private static final Logger logger = LoggerFactory.getLogger(ZipArchiveManager.class);
public static void main(String[] args) {
if (args.length < 1) {
printUsage();
System.exit(1);
}
String command = args[0].toLowerCase();
try {
switch (command) {
case "create":
handleCreate(args);
break;
case "extract":
handleExtract(args);
break;
case "list":
handleList(args);
break;
case "verify":
handleVerify(args);
break;
default:
System.err.println("Unknown command: " + command);
printUsage();
System.exit(1);
}
} catch (Exception e) {
logger.error("Operation failed", e);
System.err.println("Error: " + e.getMessage());
System.exit(1);
}
}
private static void handleCreate(String[] args) throws ZipException, IOException {
if (args.length < 3) {
System.err.println("Usage: create <output.zip> <source...> [-p password] [-l level] [-s splitSize]");
return;
}
String outputPath = args[1];
List<String> sources = new ArrayList<>();
String password = null;
int level = 5;
long splitSize = 0;
int i = 2;
while (i < args.length) {
switch (args[i]) {
case "-p":
password = args[++i];
break;
case "-l":
level = Integer.parseInt(args[++i]);
break;
case "-s":
splitSize = Long.parseLong(args[++i]);
break;
default:
sources.add(args[i]);
}
i++;
}
createArchive(outputPath, sources, password, level, splitSize);
}
private static void handleExtract(String[] args) throws ZipException {
if (args.length < 2) {
System.err.println("Usage: extract <archive.zip> [-o outputDir] [-p password]");
return;
}
String archivePath = args[1];
String outputDir = ".";
String password = null;
for (int i = 2; i < args.length; i++) {
if ("-o".equals(args[i]) && i + 1 < args.length) {
outputDir = args[++i];
} else if ("-p".equals(args[i]) && i + 1 < args.length) {
password = args[++i];
}
}
extractArchive(archivePath, outputDir, password);
}
private static void handleList(String[] args) throws ZipException {
if (args.length < 2) {
System.err.println("Usage: list <archive.zip> [-v] [-p password]");
return;
}
String archivePath = args[1];
boolean verbose = false;
String password = null;
for (int i = 2; i < args.length; i++) {
if ("-v".equals(args[i])) verbose = true;
else if ("-p".equals(args[i]) && i + 1 < args.length) password = args[++i];
}
listArchive(archivePath, verbose, password);
}
private static void handleVerify(String[] args) throws ZipException {
if (args.length < 2) {
System.err.println("Usage: verify <archive.zip> [-p password]");
return;
}
String archivePath = args[1];
String password = null;
for (int i = 2; i < args.length; i++) {
if ("-p".equals(args[i]) && i + 1 < args.length) password = args[++i];
}
verifyArchive(archivePath, password);
}
public static void createArchive(String outputPath, List<String> sources,
String password, int level, long splitSize)
throws ZipException, IOException {
logger.info("Creating archive: {}", outputPath);
ZipParameters parameters = new ZipParameters();
parameters.setCompressionMethod(CompressionMethod.DEFLATE);
parameters.setCompressionLevel(mapCompressionLevel(level));
if (password != null && !password.isEmpty()) {
parameters.setEncryptFiles(true);
parameters.setEncryptionMethod(EncryptionMethod.AES);
parameters.setAesKeyStrength(AesKeyStrength.KEY_STRENGTH_256);
logger.info("AES-256 encryption enabled");
}
List<File> filesToAdd = collectFiles(sources);
logger.info("Collected {} files for archiving", filesToAdd.size());
ZipFile zipFile;
if (password != null && !password.isEmpty()) {
zipFile = new ZipFile(outputPath, password.toCharArray());
} else {
zipFile = new ZipFile(outputPath);
}
if (splitSize > 0) {
zipFile.createSplitZipFile(filesToAdd, parameters, true, splitSize);
logger.info("Split archive created with split size: {} bytes", splitSize);
} else {
int count = 0;
for (File file : filesToAdd) {
if (file.isDirectory()) {
zipFile.addFolder(file, parameters);
} else {
zipFile.addFile(file, parameters);
}
count++;
System.out.printf("\rAdding files: %d/%d", count, filesToAdd.size());
}
System.out.println();
}
long archiveSize = new File(outputPath).length();
System.out.printf("Archive created: %s (%,d bytes, %d files)%n",
outputPath, archiveSize, filesToAdd.size());
logger.info("Archive created successfully: {} ({} bytes)", outputPath, archiveSize);
}
public static void extractArchive(String archivePath, String outputDir,
String password) throws ZipException {
logger.info("Extracting archive: {} to {}", archivePath, outputDir);
ZipFile zipFile;
if (password != null && !password.isEmpty()) {
zipFile = new ZipFile(archivePath, password.toCharArray());
} else {
zipFile = new ZipFile(archivePath);
}
if (!zipFile.isValidZipFile()) {
throw new ZipException("Invalid ZIP file: " + archivePath);
}
List<FileHeader> headers = zipFile.getFileHeaders();
int total = headers.size();
zipFile.extractAll(outputDir);
System.out.printf("Extracted %d entries to %s%n", total, outputDir);
logger.info("Extraction complete: {} entries", total);
}
public static void listArchive(String archivePath, boolean verbose,
String password) throws ZipException {
logger.info("Listing archive: {}", archivePath);
ZipFile zipFile;
if (password != null && !password.isEmpty()) {
zipFile = new ZipFile(archivePath, password.toCharArray());
} else {
zipFile = new ZipFile(archivePath);
}
List<FileHeader> headers = zipFile.getFileHeaders();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
long totalOriginal = 0;
long totalCompressed = 0;
if (verbose) {
System.out.printf("%-40s %12s %12s %7s %20s %s%n",
"Name", "Size", "Compressed", "Ratio", "Modified", "Method");
System.out.println("-".repeat(100));
}
for (FileHeader header : headers) {
long original = header.getUncompressedSize();
long compressed = header.getCompressedSize();
totalOriginal += original;
totalCompressed += compressed;
if (verbose) {
double ratio = original > 0 ? (1.0 - (double) compressed / original) * 100 : 0;
String dateStr = sdf.format(new Date(header.getLastModifiedTimeEpoch()));
String method = header.getCompressionMethod().name();
String name = header.getFileName();
if (name.length() > 40) name = "..." + name.substring(name.length() - 37);
System.out.printf("%-40s %,12d %,12d %6.1f%% %20s %s%n",
name, original, compressed, ratio, dateStr, method);
} else {
System.out.println(header.getFileName());
}
}
if (verbose) {
System.out.println("-".repeat(100));
double overallRatio = totalOriginal > 0
? (1.0 - (double) totalCompressed / totalOriginal) * 100 : 0;
System.out.printf("Total: %d files, %,d -> %,d bytes (%.1f%% compression)%n",
headers.size(), totalOriginal, totalCompressed, overallRatio);
}
}
public static void verifyArchive(String archivePath, String password) throws ZipException {
logger.info("Verifying archive: {}", archivePath);
ZipFile zipFile;
if (password != null && !password.isEmpty()) {
zipFile = new ZipFile(archivePath, password.toCharArray());
} else {
zipFile = new ZipFile(archivePath);
}
if (!zipFile.isValidZipFile()) {
System.out.println("Verification FAILED: Invalid ZIP file.");
return;
}
List<FileHeader> headers = zipFile.getFileHeaders();
int errorCount = 0;
for (FileHeader header : headers) {
try {
zipFile.getInputStream(header).close();
} catch (Exception e) {
errorCount++;
System.out.printf(" Error: %s - %s%n", header.getFileName(), e.getMessage());
logger.warn("Verification error for {}: {}", header.getFileName(), e.getMessage());
}
}
if (errorCount == 0) {
System.out.printf("Verification OK: %d files checked.%n", headers.size());
} else {
System.out.printf("Verification FAILED: %d errors found.%n", errorCount);
}
}
private static List<File> collectFiles(List<String> sources) throws IOException {
List<File> files = new ArrayList<>();
for (String source : sources) {
Path path = Paths.get(source);
if (Files.isRegularFile(path)) {
files.add(path.toFile());
} else if (Files.isDirectory(path)) {
Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
files.add(file.toFile());
return FileVisitResult.CONTINUE;
}
});
} else {
logger.warn("Skipping non-existent path: {}", source);
}
}
return files;
}
private static CompressionLevel mapCompressionLevel(int level) {
if (level <= 1) return CompressionLevel.FASTEST;
if (level <= 3) return CompressionLevel.FAST;
if (level <= 6) return CompressionLevel.NORMAL;
if (level <= 8) return CompressionLevel.HIGHER;
return CompressionLevel.MAXIMUM;
}
private static void printUsage() {
System.out.println("ZIP Archive Manager - Using zip4j + slf4j");
System.out.println();
System.out.println("Commands:");
System.out.println(" create <output.zip> <source...> [-p password] [-l level] [-s splitSize]");
System.out.println(" extract <archive.zip> [-o outputDir] [-p password]");
System.out.println(" list <archive.zip> [-v] [-p password]");
System.out.println(" verify <archive.zip> [-p password]");
}
}