---
title: "Class loading, wiring, and uses constraints"
chapter: "03"
---

# Class loading, wiring, and uses constraints

OSGi creates a controlled class space for each bundle.

## Delegation

Class lookup generally checks Java/platform boot delegation, the bundle's
imports, required bundles, its own content, and dynamic imports according to
framework rules. Exact details depend on the source of the request. Do not
solve class-loading bugs by adding broad boot delegation.

## Class identity

A Java type is identified by **binary name plus defining class loader**.
Two bundles may contain the same class name yet create incompatible types.
This explains failures that look impossible on a flat classpath.

## Split packages

A split package appears in more than one bundle. It makes ownership unclear and
can create inconsistent class spaces. Refactor toward one provider per package.

## Uses constraints

An exported API package may expose types from another package. The resolver's
`uses:=` constraint prevents consumer and provider from seeing incompatible
providers of that related type.

If `payments.api` exposes `Money` from `money.api`, both sides must use a
compatible wire for `money.api`. A uses-constraint error is protecting type
identity, not being arbitrary.

## Fragments

A fragment attaches content to a host bundle and has no independent lifecycle.
Fragments can supply localization, tests, native code, or implementation
patches, but increase coupling. Prefer services or normal bundles when possible.

## DynamicImport-Package

Dynamic imports postpone package discovery until class loading. They reduce
resolver evidence, hurt reproducibility, and turn deployment errors into
runtime errors. Use only for deliberate extensibility mechanisms that cannot
declare requirements upfront.

## Diagnostic sequence

1. Read the unresolved requirement exactly.
2. Inspect provider exports and versions.
3. Ask `bundle:diag`, `headers`, or framework wiring APIs.
4. Trace uses constraints and duplicate providers.
5. Fix metadata or package ownership; do not add wildcard imports.

## Feynman check

Why can two objects implement interfaces with identical text and still fail a
cast? Because their interface classes came from different defining loaders.
