Using the OSCAL Binding Context
This guide explains how to initialize and use the OscalBindingContext, which is the foundation for all OSCAL operations in liboscal-java.
Before you can read, write, or validate OSCAL documents, you need a binding context. The binding context is the central object that:
- Knows about all OSCAL document types (Catalog, Profile, SSP, etc.)
- Creates deserializers for reading OSCAL files
- Creates serializers for writing OSCAL files
- Provides access to Metapath evaluation
- Handles constraint validation
Think of it as the “factory” that produces all the tools you need for OSCAL processing. In liboscal-java, the OscalBindingContext extends the base Metaschema binding context with OSCAL-specific configuration.
The OscalBindingContext is the central entry point for working with OSCAL in liboscal-java. It provides:
- Pre-configured access to all OSCAL model types
- Serialization and deserialization capabilities
- Metapath expression support
- Constraint validation
For most use cases, use the singleton instance:
import dev.metaschema.oscal.lib.OscalBindingContext;
OscalBindingContext context = OscalBindingContext.instance();
The OscalBindingContext.instance() method returns a pre-configured context that:
- Loads all OSCAL Metaschema modules
- Registers OSCAL-specific Metapath functions
- Is thread-safe for concurrent use
- Avoids repeated module loading overhead
Once you have the context, you can work with any OSCAL document type:
import dev.metaschema.oscal.lib.model.Catalog;
import dev.metaschema.oscal.lib.model.Profile;
import dev.metaschema.oscal.lib.model.SystemSecurityPlan;
// Create deserializers
IDeserializer<Catalog> catalogReader = context.newDeserializer(
Format.JSON, Catalog.class);
IDeserializer<Profile> profileReader = context.newDeserializer(
Format.XML, Profile.class);
IDeserializer<SystemSecurityPlan> sspReader = context.newDeserializer(
Format.JSON, SystemSecurityPlan.class);
The binding context provides access to all OSCAL document types. Each type corresponds to a root element in the OSCAL specification:
| Class | Description |
|---|---|
Catalog |
OSCAL catalogs with controls and groups |
Profile |
Control selection and tailoring |
MappingCollection |
Control mapping between frameworks |
SystemSecurityPlan |
System security documentation |
ComponentDefinition |
Reusable component capabilities |
AssessmentPlan |
Security assessment planning |
AssessmentResults |
Assessment findings |
PlanOfActionAndMilestones |
POA&M tracking |
Understanding how OSCAL elements map to Java classes helps you navigate the API. The generated classes mirror the OSCAL model structure:
Each OSCAL document type has a corresponding Java class with nested classes for its components:
Catalog (root)
├── Metadata # Document metadata (title, dates, parties)
│ ├── Property # Key-value properties
│ └── Link # Related resources
├── Group # Control groupings
│ └── Control # Individual controls
│ ├── Parameter # Control parameters
│ ├── Part # Prose sections
│ └── Property # Control properties
└── BackMatter # Referenced resources
└── Resource # External documents
OSCAL uses consistent patterns across document types. Once you understand these patterns, working with any OSCAL type becomes intuitive:
| OSCAL Concept | Java Pattern | Example |
|---|---|---|
| Root element | Top-level class | Catalog, Profile |
| Nested elements | Nested classes | Catalog.Group, Control.Part |
| Required UUID | getUuid() method |
catalog.getUuid() |
| Metadata | getMetadata() method |
catalog.getMetadata() |
| Back matter | getBackMatter() method |
catalog.getBackMatter() |
| Properties | getProps() method |
Returns List<Property> |
| Links | getLinks() method |
Returns List<Link> |
Use getter methods to traverse the document structure:
Catalog catalog = deserializer.deserialize(path);
// Access metadata
Metadata metadata = catalog.getMetadata();
String title = metadata.getTitle().toString();
// Iterate through groups and controls
for (Group group : catalog.getGroups()) {
System.out.println("Group: " + group.getTitle());
for (Control control : group.getControls()) {
System.out.println(" Control: " + control.getId() + " - " + control.getTitle());
}
}
Create OSCAL documents programmatically using constructors and setters:
Catalog catalog = new Catalog();
catalog.setUuid(UUID.randomUUID());
Metadata metadata = new Metadata();
metadata.setTitle(MarkupLine.fromMarkdown("My Catalog"));
metadata.setLastModified(ZonedDateTime.now());
metadata.setVersion("1.0.0");
catalog.setMetadata(metadata);
OscalBindingContext
└── Extends BindingContext (from metaschema-databind)
└── Loads OSCAL Metaschema modules
├── oscal_catalog
├── oscal_profile
├── oscal_ssp
├── oscal_component-definition
├── oscal_assessment-plan
├── oscal_assessment-results
└── oscal_poam
For advanced use cases, you can access the underlying Metaschema:
import dev.metaschema.core.model.IModule;
// Get the OSCAL module
IModule oscalModule = context.getModuleByUri(
URI.create("http://csrc.nist.gov/ns/oscal/1.0"));
The OscalBindingContext.instance() is:
- Thread-safe for reading operations
- Immutable once created
- Suitable for use in multi-threaded applications
// Safe to use from multiple threads
ExecutorService executor = Executors.newFixedThreadPool(4);
OscalBindingContext context = OscalBindingContext.instance();
for (Path file : files) {
executor.submit(() -> {
// Each thread can safely use the same context
Catalog catalog = loadCatalog(context, file);
processCatalog(catalog);
});
}
Handle module loading errors appropriately:
try {
OscalBindingContext context = OscalBindingContext.instance();
} catch (MetaschemaException e) {
// Handle module loading failure
logger.error("Failed to load OSCAL modules", e);
throw new RuntimeException("OSCAL initialization failed", e);
}
- Use the singleton - Avoid creating multiple context instances
- Reuse the context - Pass the same context throughout your application
- Handle errors - Catch and handle
MetaschemaExceptionappropriately - Don't cache deserializers - Create new deserializers as needed; they're lightweight
Continue learning about liboscal-java with these related guides:
- Reading & Writing Data - Load and save OSCAL documents
- Resolving Profiles - Resolve profiles programmatically
- Architecture - Understand the library structure

