使用 Cloud SDK Spring 原型在本地调用 BAPI 时找不到目标

The destination could not be found when calling BAPI locally with Cloud SDK Spring archetype

我正在按照 official documentation 在 SAP Cloud Platform 和本地使用 Cloud SDK Spring 原型调用 BAPI。 Cloud SDK 版本为 3.35.0.

使用提供的 RFC 目标在 SAP Cloud Platform 上运行良好,但无法在本地找到目标。我完成了文档中的所有步骤。

下面是代码片段。

public List<CostCenter> getCostCenters() {
        
        System.setProperty("jco.destinations.dir", "C:\tools\SAP\destinationrfc");
        log.info(System.getProperty("jco.destinations.dir"));
        
        Destination destination = null;
        BapiRequestResult resultGetCostCenters = null;
        try {
            destination = DestinationAccessor.getDestination("s4x011rfc");
            log.info("Get destination successfully.");
            resultGetCostCenters = new BapiRequest("BAPI_COSTCENTER_GETLIST1")
                                       .withExporting("CONTROLLINGAREA", "BAPI0012_GEN-CO_AREA", "0010")
                                       .withTable("COSTCENTERLIST", "BAPI0012_CCLIST").end()
                                       .withTableAsReturn("BAPIRET2")
                                       .execute(destination);
            log.info("Get costcenters successfully.");
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        
        log.info("Start to get results.");
        //ResultElement re = resultGetCostCenters.get(0);
    
        return resultGetCostCenters.get("COSTCENTERLIST").getAsCollection().asList(CostCenter.class);
    }

我在文件夹“C:\tools\SAP\destinationrfc”中创建了一个 rfc 目标文件,并在我的代码中设置了系统 属性。

然后,我使用 war 部署在 Eclipse 中启动了我的应用程序(集成了 Tomcat)。应用启动成功后,测试RESTAPI触发BAPI调用,出现如下异常

com.sap.cloud.sdk.cloudplatform.connectivity.exception.DestinationAccessException: Failed to get destination with name 's4x011rfc'.
    at com.sap.cloud.sdk.cloudplatform.connectivity.DestinationAccessor.lambda$getDestination(DestinationAccessor.java:121)
    at io.vavr.control.Try.getOrElseThrow(Try.java:748)
    at com.sap.cloud.sdk.cloudplatform.connectivity.DestinationAccessor.getDestination(DestinationAccessor.java:117)
    at com.bosch.test.service.imp.CostCenterServiceImp.getCostCenters(CostCenterServiceImp.java:29)
    at com.bosch.test.controllers.CostCenterController.getCostCenters(CostCenterController.java:23)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:197)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:141)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:893)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:807)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1061)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:961)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at com.sap.cloud.sdk.cloudplatform.servlet.RequestAccessorFilter.lambda$doFilter(RequestAccessorFilter.java:75)
    at com.sap.cloud.sdk.cloudplatform.thread.AbstractThreadContextExecutor.lambda$execute[=12=](AbstractThreadContextExecutor.java:317)
    at com.sap.cloud.sdk.cloudplatform.security.SecurityContextThreadContextDecorator.lambda$decorateCallable(SecurityContextThreadContextDecorator.java:51)
    at com.sap.cloud.sdk.cloudplatform.thread.ThreadContextCallable.call(ThreadContextCallable.java:225)
    at com.sap.cloud.sdk.cloudplatform.thread.AbstractThreadContextExecutor.execute(AbstractThreadContextExecutor.java:319)
    at com.sap.cloud.sdk.cloudplatform.servlet.RequestAccessorFilter.doFilter(RequestAccessorFilter.java:75)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.boot.web.servlet.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:126)
    at org.springframework.boot.web.servlet.support.ErrorPageFilter.access[=12=]0(ErrorPageFilter.java:64)
    at org.springframework.boot.web.servlet.support.ErrorPageFilter.doFilterInternal(ErrorPageFilter.java:101)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.springframework.boot.web.servlet.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:200)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:668)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:834)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1415)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)
Caused by: com.sap.cloud.sdk.cloudplatform.cache.CacheRuntimeException: com.sap.cloud.sdk.cloudplatform.connectivity.exception.DestinationAccessException: Failed to get destination.
    at com.sap.cloud.sdk.cloudplatform.cache.CacheUtil.lambda$wrapCallableAsFunction[=12=](CacheUtil.java:45)
    at com.github.benmanes.caffeine.cache.BoundedLocalCache.lambda$doComputeIfAbsent(BoundedLocalCache.java:2343)
    at java.util.concurrent.ConcurrentHashMap.compute(ConcurrentHashMap.java:1853)
    at com.github.benmanes.caffeine.cache.BoundedLocalCache.doComputeIfAbsent(BoundedLocalCache.java:2341)
    at com.github.benmanes.caffeine.cache.BoundedLocalCache.computeIfAbsent(BoundedLocalCache.java:2324)
    at com.github.benmanes.caffeine.cache.LocalCache.computeIfAbsent(LocalCache.java:108)
    at com.github.benmanes.caffeine.cache.LocalManualCache.get(LocalManualCache.java:62)
    at com.sap.cloud.sdk.cloudplatform.connectivity.ScpCfDestinationLoader.lambda$tryGetDestinationec57ad6(ScpCfDestinationLoader.java:96)
    at io.vavr.control.Try.of(Try.java:75)
    at com.sap.cloud.sdk.cloudplatform.connectivity.ScpCfDestinationLoader.tryGetDestination(ScpCfDestinationLoader.java:95)
    at com.sap.cloud.sdk.cloudplatform.connectivity.DestinationLoaderChain.tryGetDestination(DestinationLoaderChain.java:84)
    at com.sap.cloud.sdk.cloudplatform.connectivity.DestinationLoader.tryGetDestination(DestinationLoader.java:36)
    at com.sap.cloud.sdk.cloudplatform.connectivity.DestinationAccessor.tryGetDestination(DestinationAccessor.java:139)
    ... 69 more
Caused by: com.sap.cloud.sdk.cloudplatform.connectivity.exception.DestinationAccessException: Failed to get destination.
    at com.sap.cloud.sdk.cloudplatform.connectivity.ScpCfDestinationServiceAdapter.getDestinationConfigurationAsJson(ScpCfDestinationServiceAdapter.java:202)
    at com.sap.cloud.sdk.cloudplatform.connectivity.ScpCfDestinationLoader.getDestinationConfigurationFromDestinationService(ScpCfDestinationLoader.java:214)
    at com.sap.cloud.sdk.cloudplatform.connectivity.ScpCfDestinationLoader.getDestinationConfigurationByTenant(ScpCfDestinationLoader.java:158)
    at com.sap.cloud.sdk.cloudplatform.connectivity.ScpCfDestinationLoader.getDestinationConfigurationByRetrievalStrategy(ScpCfDestinationLoader.java:131)
    at com.sap.cloud.sdk.cloudplatform.connectivity.ScpCfDestinationLoader.loadAndParseDestination(ScpCfDestinationLoader.java:108)
    at com.sap.cloud.sdk.cloudplatform.connectivity.ScpCfDestinationLoader.lambda$null[=12=](ScpCfDestinationLoader.java:98)
    at com.sap.cloud.sdk.cloudplatform.cache.CacheUtil.lambda$wrapCallableAsFunction[=12=](CacheUtil.java:42)
    ... 81 more
Caused by: com.sap.cloud.sdk.cloudplatform.resilience.ResilienceRuntimeException: com.sap.cloud.sdk.cloudplatform.thread.exception.ThreadContextExecutionException: com.sap.cloud.sdk.cloudplatform.security.exception.TokenRequestFailedException: com.sap.cloud.sdk.cloudplatform.exception.CloudPlatformException: Environment variable 'VCAP_SERVICES' is not defined.
    at com.sap.cloud.sdk.frameworks.resilience4j.Resilience4jDecorationStrategy.lambda$null(Resilience4jDecorationStrategy.java:182)
    at io.vavr.control.Try.onFailure(Try.java:659)
    at com.sap.cloud.sdk.frameworks.resilience4j.Resilience4jDecorationStrategy.lambda$decorateCallable(Resilience4jDecorationStrategy.java:181)
    at com.sap.cloud.sdk.cloudplatform.resilience.ResilienceDecorationStrategy.executeCallable(ResilienceDecorationStrategy.java:210)
    at com.sap.cloud.sdk.cloudplatform.resilience.ResilienceDecorator.executeCallable(ResilienceDecorator.java:197)
    at com.sap.cloud.sdk.cloudplatform.connectivity.ScpCfDestinationServiceAdapter.getDestinationConfigurationAsJson(ScpCfDestinationServiceAdapter.java:189)
    ... 87 more
Caused by: com.sap.cloud.sdk.cloudplatform.thread.exception.ThreadContextExecutionException: com.sap.cloud.sdk.cloudplatform.security.exception.TokenRequestFailedException: com.sap.cloud.sdk.cloudplatform.exception.CloudPlatformException: Environment variable 'VCAP_SERVICES' is not defined.
    at com.sap.cloud.sdk.cloudplatform.thread.AbstractThreadContextExecutor.execute(AbstractThreadContextExecutor.java:299)
    at com.sap.cloud.sdk.frameworks.resilience4j.DefaultThreadContextProvider.lambda$decorateCallable[=12=](DefaultThreadContextProvider.java:26)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    ... 1 more
Caused by: com.sap.cloud.sdk.cloudplatform.security.exception.TokenRequestFailedException: com.sap.cloud.sdk.cloudplatform.exception.CloudPlatformException: Environment variable 'VCAP_SERVICES' is not defined.
    at com.sap.cloud.sdk.cloudplatform.connectivity.ServiceCredentialsRetriever.getClientCredentials(ServiceCredentialsRetriever.java:35)
    at com.sap.cloud.sdk.cloudplatform.connectivity.ScpCfDestinationServiceAdapter.getAccessTokenForDestinationService(ScpCfDestinationServiceAdapter.java:212)
    at com.sap.cloud.sdk.cloudplatform.connectivity.ScpCfDestinationServiceAdapter.lambda$getDestinationConfigurationAsJson[=12=](ScpCfDestinationServiceAdapter.java:191)
    at com.sap.cloud.sdk.frameworks.resilience4j.Resilience4jDecorationStrategy.lambda$decorateCallable(Resilience4jDecorationStrategy.java:161)
    at com.sap.cloud.sdk.cloudplatform.security.SecurityContextThreadContextDecorator.lambda$decorateCallable(SecurityContextThreadContextDecorator.java:51)
    at com.sap.cloud.sdk.cloudplatform.thread.ThreadContextCallable.call(ThreadContextCallable.java:225)
    at com.sap.cloud.sdk.cloudplatform.thread.AbstractThreadContextExecutor.execute(AbstractThreadContextExecutor.java:293)
    ... 5 more
Caused by: com.sap.cloud.sdk.cloudplatform.exception.CloudPlatformException: Environment variable 'VCAP_SERVICES' is not defined.
    at com.sap.cloud.sdk.cloudplatform.ScpCfCloudPlatform.lambda$parseVcapServices(ScpCfCloudPlatform.java:174)
    at io.vavr.control.Option.getOrElseThrow(Option.java:351)
    at com.sap.cloud.sdk.cloudplatform.ScpCfCloudPlatform.parseVcapServices(ScpCfCloudPlatform.java:173)
    at com.sap.cloud.sdk.cloudplatform.ScpCfCloudPlatform.getVcapServices(ScpCfCloudPlatform.java:210)
    at com.sap.cloud.sdk.cloudplatform.ScpCfCloudPlatform.getServiceCredentials(ScpCfCloudPlatform.java:363)
    at com.sap.cloud.sdk.cloudplatform.ScpCfCloudPlatform.getServiceCredentials(ScpCfCloudPlatform.java:332)
    at com.sap.cloud.sdk.cloudplatform.connectivity.ServiceCredentialsRetriever.getClientCredentials(ServiceCredentialsRetriever.java:32)
    ... 11 more

更新

我对在环境变量中创建的目的地进行了一些测试。它工作正常。除了文档中的配置外,目标也应该在环境变量中创建。

destionation定义在环境变量中非常简单。只需要目的地名称。请注意,目标名称应与您在代码中使用的名称和在本地目录中创建的 jco 目标相同。

[{name: "s4x011rfc"}]

我们扩展了有关 运行 从本地计算机调用 BAPI 的文档。 我们添加了关于如何维护环境变量 destinationssection,它让 SAP Cloud SDK 找到目标名称。