Eclipse Fennec EMF OSGi enables the Eclipse Modeling Framework (EMF) in pure OSGi environments without any Eclipse PDE or Equinox dependencies. EMF models, packages, and factories are registered and consumed as standard OSGi services.
Note: This project was formerly known as GeckoEMF. It has been donated to the Eclipse Foundation and transitioned to the Eclipse Fennec project. A compatibility layer is provided for migration.
EMF relies on static global registries (EPackage.Registry.INSTANCE, Resource.Factory.Registry.INSTANCE) and Eclipse extension points. This makes it difficult to use in non-Equinox OSGi runtimes and prevents dynamic, service-oriented architectures.
Fennec EMF OSGi replaces these static registries with dynamic OSGi services:
ResourceSetis available as a prototype-scoped OSGi service, injectable via@ReferenceResourceSetFactorycreates pre-configuredResourceSetinstances on demandEPackageandEFactoryinstances are registered as services with metadata propertiesResource.Factoryregistrations are managed through the service registry- Service properties are dynamically updated as models appear and disappear at runtime
// Inject a ResourceSet that has the "mymodel" EPackage registered
@Reference(target = "(emf.name=mymodel)")
private ResourceSet resourceSet;
// Or inject the factory for programmatic creation
@Reference(target = "(emf.name=mymodel)")
private ResourceSetFactory resourceSetFactory;Add the Fennec EMF library to your BND workspace (cnf/build.bnd):
-library: fennecThis provides the required dependencies and the code generator. For individual modules, add to your project's bnd.bnd:
-library: enable-emfMaven coordinates (group ID: org.eclipse.fennec.emf):
org.eclipse.fennec.emf:org.eclipse.fennec.emf.osgi.bom:${fennec.version}
There are three ways to register EMF models with Fennec EMF OSGi:
The Fennec EMF code generator extends the standard EMF generator to produce OSGi-compatible code. Enable it by setting GenModel > All > OSGi Compatible to true.
The generator creates:
EPackageConfigurator-- registers the EPackage in the appropriate registryConfigurationComponent-- DS component that registers all model services
The following services are registered per model:
| Service | Properties |
|---|---|
EPackage |
emf.name, emf.nsURI, emf.fileExtension, emf.contentType, emf.protocol |
EFactory |
same as EPackage |
Resource.Factory (if generated) |
same as EPackage |
Condition |
all model-related properties |
In a BND workspace, code generation is configured in bnd.bnd:
-generate: \
model/mymodel.genmodel; \
generate=fennecEMF; \
genmodel=model/mymodel.genmodel; \
output=src
-includeresource: model=modelThe extender (org.eclipse.fennec.emf.osgi.extender) automatically discovers and registers .ecore models from bundles at runtime -- no code generation required.
Add this to your bundle's bnd.bnd:
Require-Capability: \
osgi.extender; \
filter:="(osgi.extender=emf.model)"
-includeresource: model=modelPlace .ecore files in the model/ folder and the extender will register them as EPackage and EPackageConfigurator services automatically.
See the full Extender Documentation for custom paths, inline properties, and annotations.
Register models dynamically via OSGi Configuration Admin using the DynamicPackageLoader factory PID:
{
"DynamicPackageLoader~demo": {
"emf.dynamicEcoreUri": "https://example.org/demo/demo.ecore",
"emf.feature": ["foo", "bar"],
"emf.feature.my": "own"
}
}The model is loaded from the given URI and registered with the following properties derived from the EPackage:
| Property | Source |
|---|---|
emf.name |
EPackage.getName() |
emf.nsURI |
EPackage.getNsURI() |
emf.feature |
forwarded from configuration |
emf.feature.* |
prefix-stripped and forwarded (e.g., emf.feature.my=own becomes my=own) |
Changing dynamicEcoreUri triggers unregistration of the old model and re-registration from the new URI. Changing other properties updates the service properties without re-loading.
Configurators are services that customize the EMF setup. Register your own implementations with the emf.configuratorName property:
| Interface | Purpose |
|---|---|
EPackageConfigurator |
Registers an EPackage in the EPackage registry |
ResourceFactoryConfigurator |
Registers resource factories in the ResourceFactory registry |
ResourceSetConfigurator |
Configures a ResourceSet before it is handed to consumers |
All EMF services use standardized properties defined in EMFNamespaces:
| Property | Type | Description |
|---|---|---|
emf.name |
String+ |
Model name(s) |
emf.nsURI |
String+ |
Model namespace URI(s) |
emf.fileExtension |
String+ |
File extensions for resource factories |
emf.protocol |
String+ |
Protocol schemes for resource factories |
emf.contentType |
String+ |
Content type identifiers |
emf.version |
String |
Model version |
emf.feature |
String+ |
Feature tags for filtering |
emf.configuratorName |
String |
Configurator name |
emf.dynamicEcoreUri |
String |
URI for dynamic model loading |
Properties are automatically propagated: when a configurator is added or removed, the ResourceSet and ResourceSetFactory service properties are updated to reflect the current set of available models.
Custom properties can be forwarded through the Fennec EMF stack using the emf.feature. prefix. For example, setting emf.feature.foo=bar on a configurator results in foo=bar appearing on the ResourceSet and ResourceSetFactory service properties. This works for all configurators and dynamic model registration.
For advanced scenarios, Fennec EMF provides configurable DS components that create dedicated, isolated EMF stacks via OSGi Configuration Admin. This is useful for multi-tenant applications or when multiple independent model sets are needed.
See the Configuration Guide for full details, factory PIDs, and JSON examples.
| Module | Description |
|---|---|
org.eclipse.fennec.emf.osgi.api |
Public API: interfaces, configurators, constants, annotations |
org.eclipse.fennec.emf.osgi |
Core implementation: DS components, registries, ResourceSet factories |
org.eclipse.fennec.emf.osgi.codegen |
BND-based EMF code generator for OSGi-compatible model code |
org.eclipse.fennec.emf.osgi.extender |
OSGi extender for automatic .ecore model registration |
org.eclipse.fennec.emf.osgi.model.info |
Runtime model introspection (EClassifier lookup by Java class) |
org.eclipse.fennec.emf.gecko.compatibility.api |
Compatibility layer for migrating from GeckoEMF |
- Configuration Guide -- Configuring EMF components via OSGi Configuration Admin
- Extender Documentation -- Automatic model registration from bundles
- EMF Delegate Registries -- Analysis of EMF's four delegate registries
- EMF Delegate User Guide -- Using invocation, setting, validation, and conversion delegates
The project uses a Gradle + BND workspace:
./gradlew build # Full build
./gradlew test # Run unit tests
./gradlew clean # Clean build artifactsRequires Java 21.
The module org.eclipse.fennec.emf.gecko.compatibility.api provides wrapper interfaces that map the old org.gecko.emf.osgi package names to the new org.eclipse.fennec.emf.osgi packages. This allows existing GeckoEMF consumers to migrate incrementally.
- Juergen Albert (jalbert) / [email protected] @ Data In Motion -- architect, developer
- Mark Hoffmann (mhoffmann) / [email protected] @ Data In Motion -- developer, architect
- Stefan Bischof (bipolis) / [email protected] -- developer
Copyright (c) Contributors to the Eclipse Foundation.
Data In Motion Consulting GmbH - [email protected]