Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Null pointer exception when Serializing Transaction with a Refund #64

Closed
vladaspasic opened this issue Aug 19, 2015 · 7 comments
Closed

Comments

@vladaspasic
Copy link

While trying to list all Transactions for a certain Client I got this NullPointerException.

This occurs when Jackson tries to serialize the Transaction that contains a Refund, that again contains a Transaction which does not have a responseCode property set.

When Jackson tries to access the getResponseCodeDetail method, from the Refunded transaction, this null value is compared and Java throws an Exception when unboxing the Integer value.

There should be a null check before these if checks to fix this issue.

@nikoloff
Copy link
Contributor

Hi @vladaspasic

If I understand you correctly, the null pointer is thrown from getResponseCodeDetail(). Is that the case?

cheers

@vladaspasic
Copy link
Author

Hi @nikoloff

yes, that is the method.

@nikoloff
Copy link
Contributor

Hi @vladaspasic
can you give me the stack trace. I can't see where the null pointer comes from.
If the method getResponseCode() returns null, the getResponseCodeDetail() will also returns null.

cheers

@vladaspasic
Copy link
Author

Hi @nikoloff

here is the stacktrace of the Exception:

java.lang.NullPointerException: null
    at com.paymill.models.Transaction.getResponseCodeDetail(Transaction.java:179) ~[paymill-java-5.1.0.jar:na]
    at gymcarry.de.api.controllers.PaymillController.findTransactions(PaymillController.java:73) ~[bin/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_25]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_25]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_25]
    at java.lang.reflect.Method.invoke(Method.java:483) ~[na:1.8.0_25]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) ~[spring-web-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137) ~[spring-web-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) ~[spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:776) ~[spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:705) ~[spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959) ~[spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) ~[spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967) ~[spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:858) ~[spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:622) ~[tomcat-embed-core-8.0.23.jar:8.0.23]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843) ~[spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) ~[tomcat-embed-core-8.0.23.jar:8.0.23]

As you can see the exception occurs on the first line in this method :

/**
   * Returns the response code as detailed message.
   * @return the message or <code>null</code> if no message is available.
   */
  public String getResponseCodeDetail() {
    if( getResponseCode() == 10001 ) {
      return "General undefined response";
    } else if( getResponseCode() == 10002 ) {...

Because the getResponseCode returns an Integer, which is not a primitive type, it's value needs to be unboxed to perform the comparison. When Java tries to unbox that value, it throws an Exception.

You can check the explanation here: http://stackoverflow.com/questions/3352791/why-comparing-integer-with-int-can-throw-nullpointerexception-in-java

@nikoloff
Copy link
Contributor

fixed in v5.1.1.

thx @vladaspasic for the clarification about the java unboxing :)

@vladaspasic
Copy link
Author

Thank you @nikoloff

I have just updated the dependency, the error is gone, but I found a new one :(

Caused by: java.lang.NullPointerException: null
    at com.paymill.models.Transaction.isSuccessful(Transaction.java:269) ~[paymill-java-5.1.1.jar:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_25]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_25]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_25]
    at java.lang.reflect.Method.invoke(Method.java:483) ~[na:1.8.0_25]
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:466) ~[jackson-databind-2.4.6.jar:2.4.6]
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:639) ~[jackson-databind-2.4.6.jar:2.4.6]
    ... 89 common frames omitted

It is the same problem like before, but in a different method, this one happens here:

  /**
   * Checks if the transaction was successful. Utility method, checks if the response_code is 20000.
   * @return true if successful, false otherwise
   */
  public boolean isSuccessful() {
    return getResponseCode() == 20000;
  }

@nikoloff
Copy link
Contributor

Hi @vladaspasic

10x again for the report will deploy new fix today

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants