java.lang.NullPointerException: null 오류가 어느 순간 부터 발생되는데 원인이 무었일까요..ㅠㅠ

항상 포럼의 도움을 많이 받는 개발자입니다.
얼마 전 까지 사용 하던 지갑 기능으로 어느 순간 부터 java.lang.NullPointerException: null 오류가 발생 합니다.
어느 부분이 문제 일런지요?
답변 부탁드립니다.

=== 버전 정보 ===
klaytn.caver : 1.4.0
JDK : 1.8

코드 :

public Map<String , String> klayTokenTranjectstion(
String password ,
String fromAddress ,
String useGasPrice ,
String toAddress ,
String amount ,
String contractAddress) throws IOException, CipherException {

    HashMap<String, String> getTransferData = new HashMap<String, String>();
    DefaultBlockParameter blockParameter = DefaultBlockParameterName.PENDING;
    //BigInteger gasLimit = new DefaultGasProvider().getGasLimit();
    BigInteger gasLimit = BigInteger.valueOf(100_000L);

    KlayCredentials senderCredential = KlayWalletUtils.loadCredentials(password, WALLET_PATH + fromAddress + ".json"); // caver-java
    int chainId = ChainId.BAOBAB_TESTNET;
    if(NODE_TYPE.equals("idc")){
        chainId = ChainId.MAINNET;
    }



        HttpService httpService = new HttpService("https://node-api.klaytnapi.com/v1/klaytn");

        String auth = Credentials.basic(klaythAccessKeyId, klaythSecretAccessKey, StandardCharsets.UTF_8);
        httpService.addHeader("Authorization", auth);
        httpService.addHeader("x-chain-id", String.valueOf(chainId));

        Caver caver = Caver.build(httpService);

        BigDecimal  sendAmount = new BigDecimal(amount);
        BigInteger value = org.web3j.utils.Convert.toWei(sendAmount, org.web3j.utils.Convert.Unit.ETHER).toBigInteger();
        BigInteger value2 = Convert.fromPeb(sendAmount , KLAY ).toBigInteger();
        System.out.println("amount:"+ value);
        System.out.println("toAddr:"+toAddress);

        Function function = new Function(
                "transfer",
                Arrays.asList(
                        new Address(toAddress),
                        new Uint256(value)
                ),
                Arrays.asList(new TypeReference<Bool>() {
                }));

        // Using web3j FunctionEncoder is fine
        String functionCallData = FunctionEncoder.encode(function);
        TransactionManager manager = new TransactionManager.Builder(caver, senderCredential)
                .setTransactionReceiptProcessor(new PollingTransactionReceiptProcessor(caver, 1000, 10))
                .setChaindId(chainId)
                .build();


        KlayTransactionReceipt.TransactionReceipt receipt = manager.executeTransaction(
                SmartContractExecutionTransaction.create(
                        senderCredential.getAddress(),
                        contractAddress,
                        BigInteger.ZERO, // value should set to zero unless you are transferring KLAY to the contract
                        Numeric.hexStringToByteArray(functionCallData), // use Numeric.hexStringToByteArray for safe conversion
                        gasLimit)
            );

 //   System.out.println(receipt.getStatus()); // 0x1
    getTransferData.put("tx status", receipt.getStatus());
    getTransferData.put("status","200");
    getTransferData.put("msg","success");
    getTransferData.put("hash",receipt.getTransactionHash());


    getTransferData.put("addr",senderCredential.getAddress());
    getTransferData.put("toAddress" , toAddress);
    getTransferData.put("contractAddress",contractAddress);
    getTransferData.put("amount" , amount);


    return getTransferData;
}

안녕하세요.
어느부분에서 에러가 발생하는지 Exception log 전달 부탁드립니다.

안녕하세요.
manager.executeTransaction 를 처리한 receipt 에서 Exception 오류가 발생 하며,
에러 로그는 아래의 내용입니다.

오류 항목에서 TranjectstionService.java:521 라인은 receipt.getTransactionHash() 값을 map 으로 넣는 부분
getTransferData.put(“tx”, receipt.getTransactionHash()); 해당 라인입니다.

오류 내용 :

java.lang.NullPointerException: null
at com.klaywallet.service.TranjectstionService.newKlayTokenTranjectstion(TranjectstionService.java:521) ~[classes/:na]
at com.klaywallet.controller.KlayWalletRestController.klayTokenTranjectstion(KlayWalletRestController.java:122) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_221]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_221]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_221]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_221]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.2.3.RELEASE.jar:5.2.3.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.2.3.RELEASE.jar:5.2.3.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106) ~[spring-webmvc-5.2.3.RELEASE.jar:5.2.3.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:888) ~[spring-webmvc-5.2.3.RELEASE.jar:5.2.3.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793) ~[spring-webmvc-5.2.3.RELEASE.jar:5.2.3.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.2.3.RELEASE.jar:5.2.3.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) ~[spring-webmvc-5.2.3.RELEASE.jar:5.2.3.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.3.RELEASE.jar:5.2.3.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.3.RELEASE.jar:5.2.3.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) ~[spring-webmvc-5.2.3.RELEASE.jar:5.2.3.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:660) ~[tomcat-embed-core-9.0.30.jar:9.0.30]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.2.3.RELEASE.jar:5.2.3.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) ~[tomcat-embed-core-9.0.30.jar:9.0.30]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.30.jar:9.0.30]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.30.jar:9.0.30]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.30.jar:9.0.30]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.30.jar:9.0.30]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.30.jar:9.0.30]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.2.3.RELEASE.jar:5.2.3.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.3.RELEASE.jar:5.2.3.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.30.jar:9.0.30]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.30.jar:9.0.30]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.2.3.RELEASE.jar:5.2.3.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.3.RELEASE.jar:5.2.3.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.30.jar:9.0.30]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.30.jar:9.0.30]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.2.3.RELEASE.jar:5.2.3.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.3.RELEASE.jar:5.2.3.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.30.jar:9.0.30]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.30.jar:9.0.30]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.30.jar:9.0.30]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-9.0.30.jar:9.0.30]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) [tomcat-embed-core-9.0.30.jar:9.0.30]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) [tomcat-embed-core-9.0.30.jar:9.0.30]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.30.jar:9.0.30]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [tomcat-embed-core-9.0.30.jar:9.0.30]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [tomcat-embed-core-9.0.30.jar:9.0.30]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:367) [tomcat-embed-core-9.0.30.jar:9.0.30]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat-embed-core-9.0.30.jar:9.0.30]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:860) [tomcat-embed-core-9.0.30.jar:9.0.30]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1598) [tomcat-embed-core-9.0.30.jar:9.0.30]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.30.jar:9.0.30]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_221]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_221]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.30.jar:9.0.30]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_221]

안녕하세요.
Transaction receipt을 가져오는 부분에서 제대로 못가져온 것 같은데요.

Transaction Receipt을 못가져오는 이유는 여러가지가 있을 수 있습니다.

  • Transaction 전송 시 실패한 경우(balance 부족 등)
    • 이 부분은 Node와 클라이언트 사이에서 주고 받는 Http Request / Response를 확인해보시면 도움 될 것 같습니다.
  • 네트워크 부하가 발생하여 Node로 부터 Receipt을 받아오는 데 시간이 오래걸린 경우
    • 이 경우 PollingTransactionReceiptProcessor의 파라미터를 수정하셔서 좀 더 오래 polling하도록 수정해보시기 바랍니다.
1개의 좋아요

제가 현제 사용한 코드에 대해서 문제점은 없는지요? 예를 들어 사용하는 함수의 지원이 종료 되었다던지, 업데이트 되면서 같은 기능이지만 명칭이 변경 되었다던지 하는 부분으로요…
말씀 하신 부분으로 수량 및 파라미터 부분으로만 체크 하면 될런지요?

코드상에 문제는 없어보입니다.
개발에 도움 되실 수 있도록 caver-java 1.4.0의 튜토리얼 링크 전달드립니다.

SDK의 사용은 개발자분들의 몫이므로 배포된 어떤 버전이든 자유롭게 사용하셔도 됩니다만, SDK를 개발하고 유지보수하는 입장에서는 caver-java의 최신버전을 사용하라고 권장드리고 싶습니다.

그리고 1.4버전의 API들은 Deprecated되어 유지보수가 되고 있지 않습니다.
하지만 1.5버전부터 인터페이스가 많이 달라져서 익숙해지는데 시간이 걸리실 수 있습니다.

1개의 좋아요

@Kale 님 께서 말씀 해주셨던 사례들을 하나 하나 체크 하면서 원인을 찾았습니다.

        BigInteger GAS_LIMIT = GAS_PROVIDER.getGasLimit();
        Quantity klayGetGasPrice = caver.klay().getGasPrice().send();

해당 코드로 인하여 실제 발생되는 수수료 보다 높게 설정된 값을 확인 후
아래와 같이 수정 하였더니 정상으로 되었습니다.
혹시 저와 같은 상황이 있는 분들 계실거 같아서… 몇자 적어요.

아래의 코드로 리미트를 고정 하니 정상으로 되었습니다.
BigInteger GAS_LIMIT = BigInteger.valueOf(100_000L);

도움 주심 Kale 님 감사합니다.

추 후 1.4 이상 버전으로 시간적 여유를 두고 다시 공부 해봐야겠군요.

1개의 좋아요