@@ -306,7 +306,10 @@ public B readTimeout(int readTimeout) {
306
306
protected ServiceOptions (Class <? extends ServiceFactory <ServiceT , OptionsT >> serviceFactoryClass ,
307
307
Class <? extends ServiceRpcFactory <ServiceRpcT , OptionsT >> rpcFactoryClass ,
308
308
Builder <ServiceT , ServiceRpcT , OptionsT , ?> builder ) {
309
- projectId = checkNotNull (builder .projectId != null ? builder .projectId : defaultProject ());
309
+ projectId = builder .projectId != null ? builder .projectId : defaultProject ();
310
+ if (projectIdRequired ()) {
311
+ checkNotNull (projectId );
312
+ }
310
313
host = firstNonNull (builder .host , defaultHost ());
311
314
httpTransportFactory = firstNonNull (builder .httpTransportFactory ,
312
315
getFromServiceLoader (HttpTransportFactory .class , DefaultHttpTransportFactory .INSTANCE ));
@@ -325,6 +328,16 @@ protected ServiceOptions(Class<? extends ServiceFactory<ServiceT, OptionsT>> ser
325
328
clock = firstNonNull (builder .clock , Clock .defaultClock ());
326
329
}
327
330
331
+ /**
332
+ * Returns whether a service requires a project ID. This method may be overridden in
333
+ * service-specific Options objects.
334
+ *
335
+ * @return true if a project ID is required to use the service, false if not.
336
+ */
337
+ public boolean projectIdRequired () {
338
+ return true ;
339
+ }
340
+
328
341
private static AuthCredentials defaultAuthCredentials () {
329
342
// Consider App Engine. This will not be needed once issue #21 is fixed.
330
343
if (appEngineAppId () != null ) {
@@ -462,6 +475,8 @@ public ServiceRpcT rpc() {
462
475
463
476
/**
464
477
* Returns the project id.
478
+ *
479
+ * Return value can be null (for services that don't require a project id).
465
480
*/
466
481
public String projectId () {
467
482
return projectId ;
0 commit comments