or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

buffer-management.mdbuilders-factories.mdcore-utilities.mdindex.mdload-balancing-name-resolution.mdservice-providers.mdtransport-layer.md

service-providers.mddocs/

0

# Service Providers

1

2

gRPC Core exposes its primary functionality through Java's Service Provider Interface (SPI) mechanism. This allows automatic discovery and registration of core gRPC functionality without requiring direct API calls.

3

4

## Capabilities

5

6

### Load Balancer Provider Registration

7

8

Registers the default pick-first load balancing strategy with the gRPC framework.

9

10

```java { .api }

11

/**

12

* Service registration: META-INF/services/io.grpc.LoadBalancerProvider

13

* Implementation: io.grpc.internal.PickFirstLoadBalancerProvider

14

*/

15

class PickFirstLoadBalancerProvider extends LoadBalancerProvider {

16

/**

17

* Indicates if this provider is available for use

18

* @return true if the provider can be used

19

*/

20

public boolean isAvailable();

21

22

/**

23

* Gets the priority of this provider relative to others

24

* @return priority value (higher numbers indicate higher priority)

25

*/

26

public int getPriority();

27

28

/**

29

* Gets the policy name for this load balancer

30

* @return "pick_first" - the name used in service config

31

*/

32

public String getPolicyName();

33

34

/**

35

* Creates a new load balancer instance

36

* @param helper Helper providing access to channel functionality

37

* @return PickFirstLoadBalancer instance

38

*/

39

public LoadBalancer newLoadBalancer(LoadBalancer.Helper helper);

40

}

41

```

42

43

**Usage:**

44

45

```java

46

import java.util.ServiceLoader;

47

import io.grpc.LoadBalancerProvider;

48

49

// Automatic discovery via SPI

50

ServiceLoader<LoadBalancerProvider> providers = ServiceLoader.load(LoadBalancerProvider.class);

51

for (LoadBalancerProvider provider : providers) {

52

if ("pick_first".equals(provider.getPolicyName())) {

53

LoadBalancer lb = provider.newLoadBalancer(helper);

54

break;

55

}

56

}

57

```

58

59

### Name Resolver Provider Registration

60

61

Registers DNS-based name resolution functionality with the gRPC framework.

62

63

```java { .api }

64

/**

65

* Service registration: META-INF/services/io.grpc.NameResolverProvider

66

* Implementation: io.grpc.internal.DnsNameResolverProvider

67

*/

68

class DnsNameResolverProvider extends NameResolverProvider {

69

/**

70

* Indicates if this provider is available for use

71

* @return true if DNS resolution is available

72

*/

73

protected boolean isAvailable();

74

75

/**

76

* Gets the priority of this provider relative to others

77

* @return priority value for DNS resolution (5 for DNS)

78

*/

79

protected int priority();

80

81

/**

82

* Gets the default URI scheme handled by this provider

83

* @return "dns" - the scheme for DNS-based name resolution

84

*/

85

public String getDefaultScheme();

86

87

/**

88

* Creates a new name resolver for the given target URI

89

* @param targetUri The target URI to resolve (e.g., dns:///example.com:443)

90

* @param args Arguments containing channel configuration

91

* @return DnsNameResolver instance or null if URI is not supported

92

*/

93

public NameResolver newNameResolver(URI targetUri, NameResolver.Args args);

94

95

/**

96

* Returns the socket address types this provider produces

97

* @return Collection containing InetSocketAddress.class

98

*/

99

public Collection<Class<? extends SocketAddress>> getProducedSocketAddressTypes();

100

}

101

```

102

103

**Usage:**

104

105

```java

106

import java.net.URI;

107

import java.net.SocketAddress;

108

import java.util.Collection;

109

import java.util.ServiceLoader;

110

import io.grpc.NameResolverProvider;

111

112

// Automatic discovery via SPI

113

URI targetUri = URI.create("dns:///example.com:443");

114

ServiceLoader<NameResolverProvider> providers = ServiceLoader.load(NameResolverProvider.class);

115

116

for (NameResolverProvider provider : providers) {

117

NameResolver resolver = provider.newNameResolver(targetUri, args);

118

if (resolver != null) {

119

resolver.start(listener);

120

break;

121

}

122

}

123

```

124

125

## Service Discovery Process

126

127

gRPC automatically discovers and loads service providers during framework initialization:

128

129

1. **Classpath Scanning**: gRPC scans for `META-INF/services/` files matching interface names

130

2. **Provider Loading**: Service providers are loaded using `ServiceLoader.load()`

131

3. **Priority Ordering**: Providers are ordered by priority (higher numbers first)

132

4. **Availability Check**: Only available providers are considered for use

133

5. **Default Selection**: The highest priority available provider becomes the default

134

135

## Provider Interface Contracts

136

137

### LoadBalancerProvider Contract

138

139

```java { .api }

140

abstract class LoadBalancerProvider {

141

/**

142

* Whether this provider is available for use

143

*/

144

public abstract boolean isAvailable();

145

146

/**

147

* A priority, from 0 to 10 that this provider should be used, higher priority wins

148

*/

149

public abstract int getPriority();

150

151

/**

152

* The policy name for this provider, which makes it selectable via service config

153

*/

154

public abstract String getPolicyName();

155

156

/**

157

* Creates a LoadBalancer for the given helper

158

*/

159

public abstract LoadBalancer newLoadBalancer(LoadBalancer.Helper helper);

160

161

/**

162

* Parses the given LoadBalancingPolicy into configuration for this provider

163

*/

164

public ConfigOrError parseLoadBalancingPolicyConfig(Map<String, ?> rawLoadBalancingPolicyConfig);

165

}

166

```

167

168

### NameResolverProvider Contract

169

170

```java { .api }

171

abstract class NameResolverProvider {

172

/**

173

* Whether this provider is available for use

174

*/

175

protected abstract boolean isAvailable();

176

177

/**

178

* A priority, from 0 to 10 that this provider should be used, higher priority wins

179

*/

180

protected abstract int priority();

181

182

/**

183

* Returns the default scheme for this provider

184

*/

185

public abstract String getDefaultScheme();

186

187

/**

188

* Creates a NameResolver for the given target URI, or null if not supported

189

*/

190

public abstract NameResolver newNameResolver(URI targetUri, NameResolver.Args args);

191

192

/**

193

* Returns the socket address types this provider produces

194

*/

195

public Collection<Class<? extends SocketAddress>> getProducedSocketAddressTypes();

196

}

197

```

198

199

## Error Handling

200

201

Service providers handle errors gracefully:

202

203

- **Unavailable Provider**: `isAvailable()` returns false if provider cannot be used

204

- **Unsupported URI**: `newNameResolver()` returns null for unsupported target URIs

205

- **Configuration Errors**: Provider configuration errors are wrapped in `ConfigOrError` objects

206

- **Runtime Errors**: Runtime errors during provider operations are propagated as gRPC Status errors