Question

I'm trying to run a QuickBooks Online batch job using the Java SDK v2.2.1 with ipp v3:

public int updateQuickBooks(BatchOperation batch) {

    OAuthAuthorizer oauth = new OAuthAuthorizer(
        consumerKey, consumerSecret, accessToken, accessTokenSecret);
    assert(oauth != null);

    Context context = new Context(oauth, QuickBooks.APP_TOKEN, ServiceType.QBO, realmID);
    assert(context != null);

    DataService service = new DataService(context);
    assert(service != null);

    LOG.info("Executing QuickBooks batch operation for " + batch.getBIds().size() + " invoices");
    service.executeBatch(batch);

...and the stack trace for the error:

java.lang.NullPointerException
at com.intuit.ipp.interceptors.ConnectionInterceptor.getRetryHandler(ConnectionInterceptor.java:212)
at com.intuit.ipp.interceptors.ConnectionInterceptor.execute(ConnectionInterceptor.java:85)
at com.intuit.ipp.interceptors.IntuitInterceptorProvider.executeRequestInterceptors(IntuitInterceptorProvider.java:76)
at com.intuit.ipp.interceptors.IntuitInterceptorProvider.executeInterceptors(IntuitInterceptorProvider.java:62)
at com.intuit.ipp.services.DataService.executeBatch(DataService.java:387)
at ie.search4less.quickbooks.InvoiceGenerator.updateQuickBooks(InvoiceGenerator.java:120)
at ie.search4less.quickbooks.FileUploadServlet.doPost(FileUploadServlet.java:79)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
at com.google.appengine.api.socket.dev.DevSocketFilter.doFilter(DevSocketFilter.java:74)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.ResponseRewriterFilter.doFilter(ResponseRewriterFilter.java:127)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.HeaderVerificationFilter.doFilter(HeaderVerificationFilter.java:34)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:63)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:125)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.DevAppServerModulesFilter.doDirectRequest(DevAppServerModulesFilter.java:366)
at com.google.appengine.tools.development.DevAppServerModulesFilter.doDirectModuleRequest(DevAppServerModulesFilter.java:349)
at com.google.appengine.tools.development.DevAppServerModulesFilter.doFilter(DevAppServerModulesFilter.java:116)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
at com.google.appengine.tools.development.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:98)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:491)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:326)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:938)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:755)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)

You can see from the stack trace that it's the executeBatch() function of DataService that's causing the error.

I'm testing this on a Google App Engine dev server running on localhost. I'm getting through the oAuth process without problems and I'm getting access key and access secret just fine. I'm using my development App Token and Consumer Key/Secret, and I'm absolutely sure that the credentials are correct.

For what it's worth, I changed the accessToken to some hardcoded random string value but the error is the same. It seems like the SDK can't communicate at all with the API endpoint. Is this maybe an issue with the App Engine environment?

Update:

I just came across this similar question and I tried removing my qbapihelper-1.2.0-with-dependencies jar (I only have that and the devkit-2.2.1-with-dependencies jar) but it didn't make a difference.

Update-2:

It seems this is an issue with using GAE and the java SDK for QBO, but unfortunately I don't have time to debug the issue further, so I've switched to my own web server (using Jetty - which is what GAE uses so not much work to port).

Was it helpful?

Solution

I would suggest you to try it from your system(not using GAE). If it works well, then you may need to configure your GAE env(may be some proxy settings ? or limited outbound requests etc).

I tried the following code and it worked fine.

public void createNoOfPurchaseUsingBatch(int noOfPurchaseInBatch) {

    BatchOperation batchOperation = new BatchOperation();

    for (int i = 1; i <= noOfPurchaseInBatch; i = i + 1) {
        Customer customer = createCustomer();
        batchOperation.addEntity(customer, OperationEnum.CREATE, "bID" + i);
    }
    try {
        this.service.executeBatch(batchOperation);
    } catch (FMSException e) {
        e.printStackTrace();
    }
}

private Customer createCustomer() {
    Customer cust = new Customer();
    cust.setDisplayName("HelloWorld " + UUID.randomUUID().toString().substring(0, 5));
    return cust;
}

Request

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<IntuitBatchRequest xmlns="http://schema.intuit.com/finance/v3">
    <BatchItemRequest bId="bID1" operation="create">
        <Customer>
            <DisplayName>HelloWorld 0d89f</DisplayName>
        </Customer>
    </BatchItemRequest>
    <BatchItemRequest bId="bID2" operation="create">
        <Customer>
            <DisplayName>HelloWorld 90251</DisplayName>
        </Customer>
    </BatchItemRequest>
</IntuitBatchRequest>

Response

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<IntuitResponse xmlns="http://schema.intuit.com/finance/v3" time="2014-05-01T06:56:43.373-07:00">
    <BatchItemResponse bId="bID1">
        <Customer domain="QBO" sparse="false">
            <Id>7</Id>
            <SyncToken>0</SyncToken>
            <MetaData>
                <CreateTime>2014-05-01T06:56:43-07:00</CreateTime>
                <LastUpdatedTime>2014-05-01T06:56:43-07:00</LastUpdatedTime>
            </MetaData>
            <FullyQualifiedName>HelloWorld 0d89f</FullyQualifiedName>
            <DisplayName>HelloWorld 0d89f</DisplayName>
            <PrintOnCheckName>HelloWorld 0d89f</PrintOnCheckName>
            <Active>true</Active>
            <Taxable>false</Taxable>
            <Job>false</Job>
            <BillWithParent>false</BillWithParent>
            <Balance>0</Balance>
            <BalanceWithJobs>0</BalanceWithJobs>
            <CurrencyRef name="Australian Dollar">AUD</CurrencyRef>
            <PreferredDeliveryMethod>Email</PreferredDeliveryMethod>
        </Customer>
    </BatchItemResponse>
    <BatchItemResponse bId="bID2">
        <Customer domain="QBO" sparse="false">
            <Id>8</Id>
            <SyncToken>0</SyncToken>
            <MetaData>
                <CreateTime>2014-05-01T06:56:43-07:00</CreateTime>
                <LastUpdatedTime>2014-05-01T06:56:43-07:00</LastUpdatedTime>
            </MetaData>
            <FullyQualifiedName>HelloWorld 90251</FullyQualifiedName>
            <DisplayName>HelloWorld 90251</DisplayName>
            <PrintOnCheckName>HelloWorld 90251</PrintOnCheckName>
            <Active>true</Active>
            <Taxable>false</Taxable>
            <Job>false</Job>
            <BillWithParent>false</BillWithParent>
            <Balance>0</Balance>
            <BalanceWithJobs>0</BalanceWithJobs>
            <CurrencyRef name="Australian Dollar">AUD</CurrencyRef>
            <PreferredDeliveryMethod>Email</PreferredDeliveryMethod>
        </Customer>
    </BatchItemResponse>
</IntuitResponse>

Thanks

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top