I am trying to use SAP Cloud SDK to connect my app in CF with on-premise S/4. Via Destinations&Cloud Connecttor.
When I deployed the app, it crashes with the following exception (longer version at end):
Error creating bean with name 'xxx' defined in file [/home/vcap/app/BOOT-INF/classes/de/zzz/xxx/handlers/xyzHandler.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [de.zzz.xxx.handlers.xyzHandler]: Constructor threw exception; nested exception is java.lang.NoSuchFieldError: SYSTEM_USER
Code of my handler:
private final HttpDestination httpDestination = DestinationAccessor.getDestination("s4_techuser").asHttp()
.decorate(DefaultErpHttpDestination::new);
Besides that, my handler ist more or less empty. I'm just trying to call the bp api:
final BusinessPartnerService service = new DefaultBusinessPartnerService();
this.businessPartner = service.getBusinessPartnerByKey(businessPartnerId).executeRequest(this.httpDestination);
which he never executes because he breaks off beforehand
The destination is (to my knowledge) used by others. However, in nodejs and not java, otherwise I would peek there. Nobody defines a field "SYSTEM_USER". Can one of you give me a hint where this comes from?
My application.yaml
spring:
config.activate.on-profile: cloud
cds:
remote.services:
'[API_BUSINESS_PARTNER]':
destination:
type: "odata-v2"
name: "s4_techuser"
suffix: "/sap/opu/odata/sap"
There is nothing special in the mta.yaml. Only my one module which requests the xsuaa, destination and connectivity services. They are all created and the binding to the app exists as well. I'm using the sap_machine and jdk 17 and sdk version 4.8.0.
Can anyone help me? Thanks
Log:
org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:65) ~[app/:na] 2023-03-05T23:18:26.951+0000 [APP/PROC/WEB/0] OUT Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [de.zzz.xxx.handlers.xyzHandler]: Constructor threw exception; nested exception is java.lang.NoSuchFieldError: SYSTEM_USER 2023-03-05T23:18:26.951+0000 [APP/PROC/WEB/0] OUT at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:224) ~[spring-beans-5.3.25.jar:5.3.25] 2023-03-05T23:18:26.951+0000 [APP/PROC/WEB/0] OUT at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:87) ~[spring-beans-5.3.25.jar:5.3.25] 2023-03-05T23:18:26.951+0000 [APP/PROC/WEB/0] OUT at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1326) ~[spring-beans-5.3.25.jar:5.3.25] 2023-03-05T23:18:26.951+0000 [APP/PROC/WEB/0] OUT ... 25 common frames omitted 2023-03-05T23:18:26.951+0000 [APP/PROC/WEB/0] OUT Caused by: java.lang.NoSuchFieldError: SYSTEM_USER 2023-03-05T23:18:26.951+0000 [APP/PROC/WEB/0] OUT at com.sap.cloud.sdk.cloudplatform.connectivity.ScpCfDestinationLoader.isAuthenticationTypeRequiringUserTokenExchange(ScpCfDestinationLoader.java:492) ~[cloudplatform-connectivity-scp-cf-4.8.0.jar:na] 2023-03-05T23:18:26.951+0000 [APP/PROC/WEB/0] OUT at com.sap.cloud.sdk.cloudplatform.connectivity.ScpCfDestinationLoader.doesDestinationConfigurationRequireUserTokenExchange(ScpCfDestinationLoader.java:239) ~[cloudplatform-connectivity-scp-cf-4.8.0.jar:na] 2023-03-05T23:18:26.951+0000 [APP/PROC/WEB/0] OUT at com.sap.cloud.sdk.cloudplatform.connectivity.ScpCfDestinationLoader.getDestinationConfigurationByTenant(ScpCfDestinationLoader.java:219) ~[cloudplatform-connectivity-scp-cf-4.8.0.jar:na] 2023-03-05T23:18:26.951+0000 [APP/PROC/WEB/0] OUT at com.sap.cloud.sdk.cloudplatform.connectivity.ScpCfDestinationLoader.getDestinationConfigurationByRetrievalStrategy(ScpCfDestinationLoader.java:186) ~[cloudplatform-connectivity-scp-cf-4.8.0.jar:na] 2023-03-05T23:18:26.951+0000 [APP/PROC/WEB/0] OUT at com.sap.cloud.sdk.cloudplatform.connectivity.ScpCfDestinationLoader.loadAndParseDestination(ScpCfDestinationLoader.java:138) ~[cloudplatform-connectivity-scp-cf-4.8.0.jar:na] 2023-03-05T23:18:26.951+0000 [APP/PROC/WEB/0] OUT at com.sap.cloud.sdk.cloudplatform.connectivity.GetOrComputeSingleDestinationCommand.lambda$prepareCommand$0(GetOrComputeSingleDestinationCommand.java:69) ~[cloudplatform-connectivity-scp-cf-4.8.0.jar:na] 2023-03-05T23:18:26.951+0000 [APP/PROC/WEB/0] OUT at io.vavr.control.Try.of(Try.java:75) ~[vavr-0.10.4.jar:na] 2023-03-05T23:18:26.951+0000 [APP/PROC/WEB/0] OUT at io.vavr.control.Try.ofSupplier(Try.java:92) ~[vavr-0.10.4.jar:na] 2023-03-05T23:18:26.951+0000 [APP/PROC/WEB/0] OUT at com.sap.cloud.sdk.cloudplatform.connectivity.GetOrComputeSingleDestinationCommand.execute(GetOrComputeSingleDestinationCommand.java:147) ~[cloudplatform-connectivity-scp-cf-4.8.0.jar:na] 2023-03-05T23:18:26.951+0000 [APP/PROC/WEB/0] OUT at io.vavr.control.Try.flatMapTry(Try.java:490) ~[vavr-0.10.4.jar:na] 2023-03-05T23:18:26.951+0000 [APP/PROC/WEB/0] OUT at io.vavr.control.Try.flatMap(Try.java:472) ~[vavr-0.10.4.jar:na] 2023-03-05T23:18:26.951+0000 [APP/PROC/WEB/0] OUT at com.sap.cloud.sdk.cloudplatform.connectivity.ScpCfDestinationLoader$Cache.getOrComputeDestination(ScpCfDestinationLoader.java:972) ~[cloudplatform-connectivity-scp-cf-4.8.0.jar:na] 2023-03-05T23:18:26.951+0000 [APP/PROC/WEB/0] OUT at com.sap.cloud.sdk.cloudplatform.connectivity.ScpCfDestinationLoader$Cache.access$000(ScpCfDestinationLoader.java:538) ~[cloudplatform-connectivity-scp-cf-4.8.0.jar:na] 2023-03-05T23:18:26.951+0000 [APP/PROC/WEB/0] OUT at com.sap.cloud.sdk.cloudplatform.connectivity.ScpCfDestinationLoader.tryGetDestination(ScpCfDestinationLoader.java:117) ~[cloudplatform-connectivity-scp-cf-4.8.0.jar:na] 2023-03-05T23:18:26.951+0000 [APP/PROC/WEB/0] OUT at com.sap.cloud.sdk.cloudplatform.connectivity.DestinationLoaderChain.tryGetDestination(DestinationLoaderChain.java:82) ~[cloudplatform-connectivity-4.5.0.jar:na] 2023-03-05T23:18:26.951+0000 [APP/PROC/WEB/0] OUT at com.sap.cloud.sdk.cloudplatform.connectivity.DestinationLoader.tryGetDestination(DestinationLoader.java:37) ~[cloudplatform-connectivity-4.5.0.jar:na] 2023-03-05T23:18:26.951+0000 [APP/PROC/WEB/0] OUT at com.sap.cloud.sdk.cloudplatform.connectivity.DestinationAccessor.tryGetDestination(DestinationAccessor.java:142) ~[cloudplatform-connectivity-4.5.0.jar:na] 2023-03-05T23:18:26.951+0000 [APP/PROC/WEB/0] OUT at com.sap.cloud.sdk.cloudplatform.connectivity.DestinationAccessor.getDestination(DestinationAccessor.java:120) ~[cloudplatform-connectivity-4.5.0.jar:na] 2023-03-05T23:18:26.951+0000 [APP/PROC/WEB/0] OUT at de.zzz.xxx.handlers.xyzHandler.(xyzHandler.java:38) ~[classes/:na]
Handler.class
@Component
@ServiceName(xyzService_.CDS_NAME)
public class xyzHandler implements EventHandler {
private final HttpDestination httpDestination = DestinationAccessor.getDestination("s4_techuser").asHttp()
.decorate(DefaultErpHttpDestination::new);
private BusinessPartner businessPartner;
private List<BusinessPartnerAddress> businessPartnerAddresses;
private List<BusinessPartnerContact> businessPartnerContacts;
private List<CustomerSalesArea> businessPartnerCustomerSalesArea;
private List<CustSalesPartnerFunc> custSalesPartnerFunctions;
CustFactSheetHandler() {
}
@On(event = XyzSheetContext.CDS_NAME)
public void getCustFactSheet(GetxyzSheetContext context) {
this.getBusinessPartner(context.getBusinessPartner());
/*this.getBusinessPartnerAdresses();
this.getBusinessPartnerEmail();
this.getBusinessPartnerContacts();
this.getBusinessPartnerCustomerSalesAreas();
this.mapRemoteBP();*/
}
private void getBusinessPartner(String businessPartnerId) {
final BusinessPartnerService service = new DefaultBusinessPartnerService();
this.businessPartner = service.getBusinessPartnerByKey(businessPartnerId).executeRequest(this.httpDestination);
}
}
(Semi-related answer)
I've noticed in your xyzHandler
code, you are invoking DestinationAccessor.getDestination(...)
on class initialization. While technically this should not be causing the problems above, I would suggest best practice:
destination
variable declaration/initialization into your getBusinessPartner(...)
method body. Internally SAP Cloud SDK is applying caching. So technically you will not notice a degradation in performance.If we are lucky, this resolves your issue already. I think Spring Boot is applying some magic class loading here, with the handler being an application-scoped component.