OCI对象存储Java客户端请求时出现NullPointerException问题
问题
环境信息:
- 使用OCI Java SDK版本3.17.0
- 测试环境为Java 17和19
- 同一份配置文件在Python SDK中可正常使用
配置代码:
ConfigFile ociConfig = ConfigFileReader.parse(configFile.getAbsolutePath(), profile); Supplier<InputStream> privateKeySupplier = new SimplePrivateKeySupplier(ociConfig.get("key_file")); AuthenticationDetailsProvider provider = SimpleAuthenticationDetailsProvider.builder() .tenantId(ociConfig.get("tenancy")) .userId(ociConfig.get("user")) .fingerprint(ociConfig.get("fingerprint")) .privateKeySupplier(privateKeySupplier) .build(); objectStorageClient = ObjectStorageClient .builder() .build(provider); Runtime.getRuntime().addShutdownHook(new Thread(() -> { if (objectStorageClient != null) objectStorageClient.close(); })); namespace = handleResponse(objectStorageClient.getNamespace(GetNamespaceRequest.builder().build())).getValue();
运行时抛出异常:
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.contains(java.lang.CharSequence)" because "endpoint" is null at com.oracle.bmc.http.internal.BaseClient.populateServiceParametersInEndpoint(BaseClient.java:215) at com.oracle.bmc.objectstorage.ObjectStorageClient.getNamespace(ObjectStorageClient.java:874)
解决方案
空指针异常的原因是ObjectStorageClient未配置服务端点(Endpoint)。OCI Java SDK不会像Python SDK那样自动从配置文件读取endpoint参数,必须显式指定。
修改后的代码如下:
ConfigFile ociConfig = ConfigFileReader.parse(configFile.getAbsolutePath(), profile); Supplier<InputStream> privateKeySupplier = new SimplePrivateKeySupplier(ociConfig.get("key_file")); AuthenticationDetailsProvider provider = SimpleAuthenticationDetailsProvider.builder() .tenantId(ociConfig.get("tenancy")) .userId(ociConfig.get("user")) .fingerprint(ociConfig.get("fingerprint")) .privateKeySupplier(privateKeySupplier) .build(); // 从配置文件获取endpoint:优先用region自动生成,否则直接读取配置的endpoint String endpoint; if (ociConfig.get("region") != null) { endpoint = ObjectStorageClient.builder().endpointForRegion(ociConfig.get("region")); } else { endpoint = ociConfig.get("endpoint"); } objectStorageClient = ObjectStorageClient .builder() .endpoint(endpoint) // 关键:添加端点配置 .build(provider); Runtime.getRuntime().addShutdownHook(new Thread(() -> { if (objectStorageClient != null) objectStorageClient.close(); })); namespace = handleResponse(objectStorageClient.getNamespace(GetNamespaceRequest.builder().build())).getValue();
核心说明:
- 如果配置文件包含
region字段,使用endpointForRegion方法自动生成对应区域的Object Storage端点,避免手动输入错误。 - 若配置文件直接定义了
endpoint字段,直接读取该值即可。 - Java SDK客户端构建器默认不会自动加载配置文件中的endpoint,这是和Python SDK的主要差异点。
内容的提问来源于stack exchange,提问作者Hein Gertenbach
相关产品推荐
相关产品推荐

