Skip to main content

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 the ServiceManager 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:
Reference: ~/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:
The 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:
Reference: ~/workspace/source/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/Plugin.java:249
When your plugin directly implements a service interface, do NOT call registerServiceProvided() for that service. The framework automatically registers it.

Method 2: Delegated Implementation

Delegate service implementation to a separate object:
Reference: ~/workspace/source/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/Plugin.java:637

Dynamic Service Registration

Services can be registered after plugin construction:
Reference: ~/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:
Reference: ~/workspace/source/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/Plugin.java:518

Retrieving Services

Single Implementation

Get the first available implementation:
Reference: ~/workspace/source/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/mgr/ServiceManager.java:147

Multiple Implementations

Get all available implementations:
Reference: ~/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:
Reference: ~/workspace/source/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/Plugin.java:493

Service Removed Notifications

Handle service removal gracefully:
Reference: ~/workspace/source/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/Plugin.java:507

Dependency Management

Automatic Dependency Resolution

Ghidra automatically resolves service dependencies:
  1. Plugins are constructed in dependency order
  2. Plugins wait for required services to become available
  3. init() is called only when all dependencies are met
  4. Plugins fail to load if dependencies cannot be satisfied

Checking Service Availability

Optional Dependencies

For optional services, don’t declare them in servicesRequired:

Common Service Patterns

Singleton Services

Most services have a single provider:

Multiple Provider Services

Some services allow multiple providers:
Consumers can get all providers:

Layered Services

Services can depend on other services:

Service Best Practices

Keep service interfaces focused. If a service has multiple responsibilities, consider splitting it into multiple services.
Always check for null when retrieving services that aren’t required dependencies.
Service methods may be called from multiple threads. Design services to be thread-safe or document threading requirements.
Document and handle errors appropriately in service methods.

ServiceManager API

The ServiceManager 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:
  1. Check the servicesRequired in @PluginInfo
  2. Verify the required service plugins are installed
  3. Check for circular dependencies
  4. 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.