apache/beam · error

error in extractJar()

Error message

error in extractJar(): %w

What it means

MakeJar wraps any failure from extractJar(), which unzips the downloaded Beam JAR into a temp directory so its MANIFEST.MF can be rewritten with a relocated Class-Path. A non-nil error from extractJar (zip open/read/write failure) is wrapped here with the standard Go %w pattern so callers can unwrap the root cause.

Solutions

  1. Delete the cached JAR and tmpDir under cacheDir and re-run so a fresh JAR is downloaded.
  2. Check disk space and write permissions on the cache directory.
  3. Unwrap the error (errors.Unwrap / errors.As on *zip.Error) to see whether the JAR is corrupt or the destination is unwritable.
  4. Verify the JAR was fetched from the repository correctly (non-truncated download).

Example fix

// before: blindly reusing possibly-corrupt cache
jar, err := expansionx.MakeJar(ctx, gradleTarget, repoURL, version)
// after: verify zip integrity before MakeJar
if _, err := zip.OpenReader(jarPath); err != nil {
    os.RemoveAll(filepath.Join(cacheDir, "tmpDir"))
    os.Remove(jarPath) // force fresh download
}
jar, err := expansionx.MakeJar(ctx, gradleTarget, repoURL, version)
Defensive patterns

Strategy: try-catch

Validate before calling

if _, err := os.Stat(mainJar); err != nil {
    return fmt.Errorf("main jar missing: %w", err)
}
if _, err := zip.OpenReader(mainJar); err != nil {
    os.Remove(mainJar) // corrupt cache entry, force re-download
}

Type guard

func isZipError(err error) bool {
    var ze *zip.Error
    return errors.As(err, &ze)
}

Try / catch

jar, err := expansionx.MakeJar(ctx, target, repo, version)
if err != nil && strings.Contains(err.Error(), "error in extractJar()") {
    os.RemoveAll(cacheDir) // clear cache and retry once
    jar, err = expansionx.MakeJar(ctx, target, repo, version)
}

Prevention

When it happens

Trigger: MakeJar is called (via startAutomatedJavaExpansionService) and extractJar fails: the main JAR file does not exist at the expected cache path, the file is not a valid zip archive, or the destination tmpDir cannot be created/written.

Common situations: A partial or corrupted JAR was left in the cache from an earlier failed download; disk full or permission problems on the cache directory; the JAR path computed by GetBeamJar points at a non-zip file.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/aad8874a9653d23d. Report an issue: GitHub.

Appendix: source

Thrown at sdks/go/pkg/beam/core/runtime/xlangx/expansionx/download.go:285

		} else {
			return "", fmt.Errorf("error in getLocal(): %w", err)
		}
	}

	// classpath jars should have relative path
	relClasspath := []string{}
	for _, path := range classpathJars {
		relPath, err := filepath.Rel(cacheDir, path)
		if err != nil {
			return "", fmt.Errorf("error in creating relative path: %w", err)
		}
		relClasspath = append(relClasspath, relPath)
	}

	tmpDir := filepath.Join(cacheDir, "tmpDir")

	if err := extractJar(mainJar, tmpDir); err != nil {
		return "", fmt.Errorf("error in extractJar(): %w", err)
	}

	manifest, err := os.ReadFile(tmpDir + "/META-INF/MANIFEST.MF")
	if err != nil {
		return "", fmt.Errorf("error readingf: %w", err)
	}

	// trim the empty lines present at the end of MANIFEST.MF file.
	manifestLines := strings.Split(string(manifest), "\n")
	manifestLines = manifestLines[:len(manifestLines)-2]

	classpathString := fmt.Sprintf("%sClass-Path: %s\n", strings.Join(manifestLines, "\n"), strings.Join(relClasspath, " "))
	if err = os.WriteFile(tmpDir+"/META-INF/MANIFEST.MF", []byte(classpathString), 0660); err != nil {
		return "", fmt.Errorf("error writing ta manifest file: %w", err)
	}

	path, err := os.Getwd()
	if err != nil {

View on GitHub (pinned to 12126d8942)