What does it mean to seal a package in a JAR, and how do you configure it in the manifest?
answer
- Sealed: true in MANIFEST.MF
- all classes of a package from ONE jar
- main section seals whole jar; Name: pkg/ section seals one
- violation = SecurityException at class-load time
- Sealed: false carves out an exception
basics
~20 sSealing a package means every class in that package must come from the same JAR file. You turn it on by adding 'Sealed: true' to the JAR's MANIFEST.MF, for one package or the whole archive.
solid answer
~40 sSealing forces all classes of a Java package to be loaded from a single JAR. If code tries to load a class for a sealed package from a different JAR, the class loader throws a SecurityException at load time. You enable it in META-INF/MANIFEST.MF: to seal the whole archive, put 'Sealed: true' in the main section; to seal one package, add a per-entry section 'Name: com/example/foo/' followed by 'Sealed: true'. You can also un-seal a single package with 'Sealed: false' even when the whole JAR is sealed. The point is integrity: it stops someone from slipping mismatched or malicious classes into your package by putting them in another JAR on the classpath. It is purely a packaging/class-loading guarantee, separate from (though often paired with) JAR signing.
code
java · 15 lines// META-INF/MANIFEST.MF (text content; not real Java, shown for layout)
//
// Manifest-Version: 1.0
// Sealed: true # seals the whole archive
//
// Name: com/example/open/ # ...but un-seal one package
// Sealed: false
//
// Name: com/example/secure/ # explicitly seal one package
// Sealed: true
// If another jar on the classpath tries to add a class to a sealed
// package, the class loader fails at load time:
// java.lang.SecurityException: sealing violation:
// package com.example.secure is sealedgo deeper
Knows sealing means 'all classes of a package come from one JAR' and that it is switched on with 'Sealed: true' in the manifest.
Can write both the whole-archive and per-package manifest entries, including 'Sealed: false' exceptions, and knows the violation is a runtime SecurityException.
Explains the threat model (package-private access / class shadowing from a rogue JAR), where the check fires (class loader), and how it differs from and complements signing.
Positions sealing against JPMS strong encapsulation, advises when each is appropriate in a packaging/dependency strategy, and reasons about its limits in modern modular builds.
## Background: JARs and packages A **JAR** (Java ARchive) is a ZIP file with a `.jar` extension that bundles compiled `.class` files plus a metadata file at `META-INF/MANIFEST.MF`. A **package** is a namespace grouping related classes, written dotted like `com.example.foo`, which maps to the directory `com/example/foo/` inside the archive. Normally the classes of one package can be spread across several JARs on the **classpath** (the list of locations the JVM searches for classes). `com.example.foo.A` might live in `app.jar` and `com.example.foo.B` in `plugin.jar`, and Java loads both without complaint. This is a flexibility, but also a risk: an attacker (or a careless dependency) could ship a JAR that adds its own class into *your* package and gain **package-private access** to your internals, or shadow/replace a class. ## What sealing does **Sealing** a package declares: *every* class in this package must be loaded from the *same* JAR. If, after a sealed package's first class is loaded from JAR X, the class loader is later asked to load another class of that package from a different source, it throws a `SecurityException`. This guarantees a sealed package is **indivisible and tamper-resistant** at the packaging level. ## How you configure it Sealing is declared entirely in `META-INF/MANIFEST.MF`, a plain-text file of `Key: value` headers organized into sections separated by blank lines. 1. **Seal the whole JAR** — put in the *main* (first) section: ``` Manifest-Version: 1.0 Sealed: true ``` Now every package in the archive is sealed. 2. **Seal one package** — add a *per-entry* section whose `Name:` is the package path (note the trailing slash): ``` Name: com/example/foo/ Sealed: true ``` 3. **Un-seal an exception** — when the whole JAR is sealed you can carve out one package: ``` Name: com/example/open/ Sealed: false ``` The most specific (per-entry) setting wins over the main-section default. ## With build tools With Maven's `maven-jar-plugin` you set `<sealed>true</sealed>` under `<manifest>`. With Gradle you add the attribute to the `jar` task's manifest: `manifest { attributes('Sealed': 'true') }`. The `jar` CLI reads attributes from a manifest you pass via `jar cfm app.jar manifest.txt ...`. ## When it actually fires Verification happens at **class-load time**, by the class loader, not at compile time and not at JAR-build time. So a sealing violation surfaces as a runtime `SecurityException` the first time a stray class of the sealed package is requested. ## Relationship to signing and to JPMS Sealing answers *“are all these classes from one JAR?”*. **JAR signing** (a separate feature) answers *“who published this JAR and has it been altered?”*. They are independent and complementary — sealing about cohesion, signing about provenance/integrity of bytes. Note that the **Java Platform Module System (JPMS, since Java 9)** offers stronger encapsulation: a module's `exports` controls which packages are visible and a *non-exported* package cannot be augmented or accessed from outside at all. Where modules are used, JPMS largely supersedes sealing for encapsulation; sealing remains a lightweight classpath-era mechanism that still works for plain (non-modular) JARs.
- At what point is a sealing violation detected?At class-load time, by the class loader. The JVM throws a SecurityException the first time a class of a sealed package is requested from a different source than the one that supplied the package's first-loaded class. It is not a compile-time or build-time check.
- How do you seal the whole JAR but leave one package open?Put 'Sealed: true' in the manifest's main section, then add a per-entry section 'Name: com/example/open/' with 'Sealed: false'. The per-entry setting overrides the global default for that package.
A sealed package is like a tamper-evident shrink-wrapped product box: every item inside must have come from that one sealed box. If a part shows up from a different box, you reject the whole thing as compromised.
saying these in an interview costs you the question
- Saying sealing encrypts or signs the classes — it does neither; it only enforces single-JAR origin.
- Confusing sealing with the 'sealed classes/interfaces' language feature (Java 17) — unrelated, that restricts which types may extend a class.
- Claiming the check happens at compile time or when building the JAR — it is a runtime class-loader check.
- Thinking sealing alone proves provenance/who published it — that is signing, a separate concern.