cancel
Showing results for 
Search instead for 
Did you mean: 

Unit testing java AuthTokenAccessor error initializing class (Cloud SDK and CAP Java)

wkorys
Discoverer
0 Kudos

Hi everyone,

I am junior programmer and I came across a problem, which I cannot solve without outside help. I am currently writing unit tests for service linked below and I don't know how to deal with mocking such as Destination, the error which I get is following java.lang.NoClassDefFoundError: Could not initialize class com.sap.cloud.sdk.cloudplatform.security.AuthTokenAccessor. It points to the destination = getDestination(); line. I will appreciate any help in order to solve this problem. I am eager to connect with somebody willing to help me sort this out. Every help will be much appreciated. Thanks

import com.auth0.jwt.JWT;<br>import com.auth0.jwt.exceptions.JWTDecodeException;<br>import com.auth0.jwt.interfaces.DecodedJWT;<br>import com.sap.cloud.sdk.cloudplatform.connectivity.Destination;<br>import com.sap.cloud.sdk.cloudplatform.connectivity.DestinationAccessor;<br>import com.sap.cloud.sdk.cloudplatform.connectivity.Header;<br>import com.sap.cloud.sdk.cloudplatform.connectivity.HttpDestination;<br>import com.sap.cloud.sdk.cloudplatform.connectivity.exception.DestinationNotFoundException;<br>import lombok.extern.slf4j.Slf4j;<br>import org.json.JSONObject;<br>import org.springframework.http.HttpEntity;<br>import org.springframework.http.HttpHeaders;<br>import org.springframework.http.HttpMethod;<br>import org.springframework.http.ResponseEntity;<br>import org.springframework.stereotype.Service;<br>import org.springframework.web.client.RestTemplate;<br><br>import javax.annotation.PostConstruct;<br>import java.net.URI;<br>import java.util.Collection;<br>import java.util.Date;<br><br>@Service<br>@Slf4j<br>public class JwtService {<br>    static final RestTemplate restTemplate = new RestTemplate();<br>    private String dieToken;<br>    private String clientId;<br>    private String clientSecret;<br>    private URI jwtTokenUri;<br>    private boolean localDev;<br>    private HttpDestination httpDestination;<br><br>    public JwtService() {<br>        Destination destination;<br>        destination = getDestination();<br><br>        httpDestination = destination.asHttp();<br>        if (localDev) {<br>            this.clientId = httpDestination.get("username").map(Object::toString).getOrElse("");<br>            this.clientSecret = httpDestination.get("password").map(Object::toString).getOrElse("");<br>            this.jwtTokenUri = httpDestination.getUri();<br>        }<br>        else {<br>            log.debug("Die service uri " + httpDestination.getUri().toString());<br><br>            this.clientId = "";<br>            this.clientSecret = "";<br>            this.jwtTokenUri = httpDestination != null ? httpDestination.getUri() : null;<br>        }<br>    }<br><br>    private Destination getDestination() {<br>        try {<br>            this.localDev = true;<br>            log.debug("Destination 'DIE_Service_JWT' found. Application should run in local env");<br>            return DestinationAccessor.getDestination("DIE_Service_JWT");<br>        } catch (DestinationNotFoundException e) {<br>            this.localDev = false;<br>            log.debug("Destination 'DIE_Service_JWT' not found. Application should run in the cloud");<br>            return DestinationAccessor.getDestination("DIE_Service");<br>        }<br>    }<br><br>    public String getDieToken() {<br>        if (dieToken == null) {<br>            getNewToken();<br>        }<br>        try {<br>            DecodedJWT decodedJWT = JWT.decode(dieToken);<br>            if (!isJWTExpired(decodedJWT)) {<br>                return dieToken;<br>            }<br>        } catch (JWTDecodeException e) {<br>            log.error(e.getLocalizedMessage());<br>        }<br>        //Get new token<br>        getNewToken();<br>        return dieToken;<br>    }<br><br>    private boolean isJWTExpired(DecodedJWT decodedJWT) {<br>        Date expiresAt = decodedJWT.getExpiresAt();<br>        return expiresAt.before(new Date());<br>    }<br><br>    private void getNewToken() {<br>        if(localDev) {<br>            HttpHeaders httpHeaders = new HttpHeaders();<br>            httpHeaders.setBasicAuth(clientId, clientSecret);<br>            HttpEntity<String> entity = new HttpEntity<>(httpHeaders);<br>            String jwtTokenUriString = jwtTokenUri.toString();<br>            ResponseEntity<String> response = restTemplate.exchange(<br>                    jwtTokenUriString,<br>                    HttpMethod.GET,<br>                    entity,<br>                    String.class<br>            );<br>            this.dieToken = new JSONObject(response.getBody()).optString("access_token");<br>        }<br>        else{<br>            this.dieToken = getTokenFromDestination(httpDestination.getHeaders(jwtTokenUri));<br><br>        }<br>    }<br><br>    @PostConstruct<br>    public void getFirstToken() {<br>        log.debug("getting first token");<br>        getNewToken();<br>    }<br><br>    private String getTokenFromDestination(Collection<Header> headers) {<br>        for(var it : headers){<br>            if(it.getValue().contains("Bearer")){<br>                String jwtToken = it.getValue().replace("Bearer ", "");<br>                jwtToken.replace("Bearer ", "");<br>                return jwtToken;<br>            }<br>        }<br>        return "";<br>    }<br>}<br>
charlesdubois
Associate
Associate
0 Kudos

It's likely a dependency problem. Could you send the dependency tree of you application:

mvn dependency:tree
wkorys
Discoverer
0 Kudos

charlesdubois in the attachment you will find my project's dependency tree dependency-tree.txt

charlesdubois
Associate
Associate

The module liquibase has been removed since version 4, please remove it. Also are you using WAR deployment? If you want a more detailed stack-trace you could instantiate ScpCfAuthTokenFacade manually. Lastly, I recommend that you use the sdk-bom and read our dependency guide to manage your dependencies:

https://sap.github.io/cloud-sdk/docs/java/guides/manage-dependencies

View Entire Topic
0 Kudos

Did removing / replacing the liquibase dependency (as suggested by Charles) solve your issue?

wkorys
Discoverer
0 Kudos

I have added a destinations with service name, url and credentials to system variables in the run configuration of test class and managed to test it locally.