Overview
Services provide a powerful mechanism for plugins to expose functionality to other plugins. The service architecture enables loose coupling between plugins while maintaining strong contracts through Java interfaces.Service Architecture
The service system is managed by theServiceManager class, which maintains a registry of service interfaces and their implementations.
Reference: ~/workspace/source/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/mgr/ServiceManager.java:35
Key Components
- Service Interface: A Java interface defining the contract
- Service Provider: A plugin implementing the service interface
- Service Consumer: A plugin using the service
- ServiceManager: Manages registration and lookup
Defining Service Interfaces
Service interfaces are standard Java interfaces with no special requirements:~/workspace/source/Ghidra/Features/Base/src/main/java/ghidra/app/services/ClipboardService.java:18
Service Interface Guidelines
Keep It Focused
Service interfaces should have a single, well-defined responsibility
Document Contracts
Clearly document method behavior, parameters, and return values
Version Carefully
Consider backward compatibility when modifying existing services
Use Standard Types
Prefer standard types over plugin-specific classes in signatures
Service Annotations
@ServiceInfo
Optionally annotate service interfaces with@ServiceInfo to specify metadata:
defaultProvider property specifies which plugin should be auto-loaded when this service is required but no provider is currently loaded.
Providing Services
Plugins can provide services in two ways:Method 1: Direct Implementation
Implement the service interface directly in your plugin class:~/workspace/source/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/Plugin.java:249
Method 2: Delegated Implementation
Delegate service implementation to a separate object:~/workspace/source/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/Plugin.java:637
Dynamic Service Registration
Services can be registered after plugin construction:~/workspace/source/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/Plugin.java:648
Consuming Services
Declaring Dependencies
Declare required services in the@PluginInfo annotation:
~/workspace/source/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/Plugin.java:518
Retrieving Services
Single Implementation
Get the first available implementation:~/workspace/source/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/mgr/ServiceManager.java:147
Multiple Implementations
Get all available implementations:~/workspace/source/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/mgr/ServiceManager.java:163
Service Lifecycle
Service Added Notifications
Plugins can respond when services become available:~/workspace/source/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/Plugin.java:493
Service Removed Notifications
Handle service removal gracefully:~/workspace/source/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/Plugin.java:507
Dependency Management
Automatic Dependency Resolution
Ghidra automatically resolves service dependencies:- Plugins are constructed in dependency order
- Plugins wait for required services to become available
init()is called only when all dependencies are met- Plugins fail to load if dependencies cannot be satisfied
Checking Service Availability
Optional Dependencies
For optional services, don’t declare them inservicesRequired:
Common Service Patterns
Singleton Services
Most services have a single provider:Multiple Provider Services
Some services allow multiple providers:Layered Services
Services can depend on other services:Service Best Practices
Interface Segregation
Interface Segregation
Keep service interfaces focused. If a service has multiple responsibilities, consider splitting it into multiple services.
Null Safety
Null Safety
Always check for null when retrieving services that aren’t required dependencies.
Thread Safety
Thread Safety
Service methods may be called from multiple threads. Design services to be thread-safe or document threading requirements.
Error Handling
Error Handling
Document and handle errors appropriately in service methods.
ServiceManager API
TheServiceManager class provides the core service registry functionality:
Common Services in Ghidra
Here are some frequently used services:Troubleshooting
Plugin Won’t Load
If your plugin fails to load due to missing services:- Check the
servicesRequiredin@PluginInfo - Verify the required service plugins are installed
- Check for circular dependencies
- Review the application log for specific errors
Service Returns Null
Multiple Service Providers
When multiple plugins provide the same service,getService() returns an arbitrary one. Use getServices() to get all providers.
Related Documentation
- Plugin Development - Plugin lifecycle and structure
- Events - Event-based communication between plugins
