I am following the official documentation to call BAPI both on SAP Cloud Platform and locally with Cloud SDK Spring archetype. The Cloud SDK version is 3.35.0.
It works fine on SAP Cloud Platform with the RFC destination provided but the destination could not be found locally. I finished all the steps in the documentation.
Below is the code snippets.
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);
}
I created a rfc destination file in folder "C:\tools\SAP\destinationrfc" and set the system property in my code.
Then, I started up my application in Eclipse with war deployment (Tomcat was integrated). After the application was started successfully, I tested the REST API to trigger BAPI call and got the following exception.
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$1(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$1(RequestAccessorFilter.java:75)
at com.sap.cloud.sdk.cloudplatform.thread.AbstractThreadContextExecutor.lambda$execute$0(AbstractThreadContextExecutor.java:317)
at com.sap.cloud.sdk.cloudplatform.security.SecurityContextThreadContextDecorator.lambda$decorateCallable$2(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$000(ErrorPageFilter.java:64)
at org.springframework.boot.web.servlet.support.ErrorPageFilter$1.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$0(CacheUtil.java:45)
at com.github.benmanes.caffeine.cache.BoundedLocalCache.lambda$doComputeIfAbsent$14(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$tryGetDestination$2ec57ad6$1(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$0(ScpCfDestinationLoader.java:98)
at com.sap.cloud.sdk.cloudplatform.cache.CacheUtil.lambda$wrapCallableAsFunction$0(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$2(Resilience4jDecorationStrategy.java:182)
at io.vavr.control.Try.onFailure(Try.java:659)
at com.sap.cloud.sdk.frameworks.resilience4j.Resilience4jDecorationStrategy.lambda$decorateCallable$3(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$0(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$0(ScpCfDestinationServiceAdapter.java:191)
at com.sap.cloud.sdk.frameworks.resilience4j.Resilience4jDecorationStrategy.lambda$decorateCallable$1(Resilience4jDecorationStrategy.java:161)
at com.sap.cloud.sdk.cloudplatform.security.SecurityContextThreadContextDecorator.lambda$decorateCallable$2(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$1(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
I did some testing with the destination created in environment variable. It works fine. Besides the configurations in documentation, the destination should be created in environment variable as well.
The destionation definition is very simple in environment variable. Only destination name is required. Note that the destination name should be the same as what you used in code and jco destination you created in local dir.
[{name: "s4x011rfc"}]
We extended the documentation on running BAPI calls from the local machine.
We added a section on how to maintain the environment variable destinations
which lets the SAP Cloud SDK find the destination name.