BingAds / BingAds-Java-SDK

Other
43 stars 48 forks source link

OutOfMemory (OutOfResource) Error with cxf 4.0.2 #154

Open schabe77 opened 1 year ago

schabe77 commented 1 year ago

Hi,

after upgrading to version 13.0.16.2 which uses cxf 4.0.2 my software runs into OutOfMemoryErrors. It seems that cxf creates a new thread for each request. After some thousand threads were created, starting the new threads fails with java.lang.OutOfMemoryError: unable to create native thread: possibly out of memory or process/resource limits reached

Here is an example stack when invoking com.microsoft.bingads.v13.customermanagement.ICustomerManagementService#getAccount:

    at jdk.internal.net.http.HttpClientImpl$SelectorManager.<init>(HttpClientImpl.java:715)
    at jdk.internal.net.http.HttpClientImpl.<init>(HttpClientImpl.java:325)
    at jdk.internal.net.http.HttpClientImpl.create(HttpClientImpl.java:270)
    at jdk.internal.net.http.HttpClientBuilderImpl.build(HttpClientBuilderImpl.java:135)
    at org.apache.cxf.transport.http.HttpClientHTTPConduit.setupConnection(HttpClientHTTPConduit.java:231)
    at org.apache.cxf.transport.http.HTTPConduit.prepare(HTTPConduit.java:529)
    at org.apache.cxf.interceptor.MessageSenderInterceptor.handleMessage(MessageSenderInterceptor.java:47)
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
    at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:528)
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:439)
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:354)
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:312)
    at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
    at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:140)
    at jdk.proxy2.$Proxy100.getAccount(Unknown Source:-1)

I don't know if there is anything you can do (e.g. activate pooling?) or if I have to create a bug report at cxf,

schabe77 commented 1 year ago

I opened a ticket at https://issues.apache.org/jira/browse/CXF-8902

As far as I understood it the problem is, that CXF creates a new thread on each request with their new HttpClientHTTPConduit.

I found a workaround for my use case: I use spring and it's possible to provide an own HTTPConduitFactory that creates a URLConnectionHTTPConduit like e.g.

public class URLConnectionHTTPConduitFactory implements HTTPConduitFactory {
    @Override
    public HTTPConduit createConduit(HTTPTransportFactory f, Bus bus, EndpointInfo endpointInfo, EndpointReferenceType target) throws IOException {
        return new URLConnectionHTTPConduit(bus, endpointInfo, target);
    }
}

by defining it in a classpath file /cxf.xml, e.g.

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

    <bean id="org.apache.cxf.transport.http.HTTPConduitFactory" class="package.of.my.URLConnectionHTTPConduitFactory" />

</beans>