I'm running several camel routes (about 100) in JBoss Fuse. Recently I'm getting a OutOfMemoryError: Java heap space so I decided use Eclipse Memory Analyzer Tool to hunt the leaks.
The report shows several suspects, but the biggest one is this:
11.539 instances of "org.apache.http.impl.conn.PoolingHttpClientConnectionManager", loaded by "org.apache.felix.framework.BundleWiringImpl$BundleClassLoaderJava5 @ 0xd16558b8" occupy 443.624.920 (63,87%) bytes.
Unlike other leaks problems, the details report for this case is small, is just 4 lines:
class java.lang.Thread @ 0xd0a9c0c8
\class org.apache.camel.component.jms.DefaultJmsMessageListenerContainer @ 0xd367ee58 .\class org.apache.camel.component.jms.JmsQueueEndpoint @ 0xd36750d8
..\class org.apache.camel.blueprint.BlueprintCamelContext @ 0xd33bcd50
It seems that something is wrong with the http connections, but I really don't know.
I use the http component in pollEnrichers like this:
from(URI_COLA_ENTRADA_STEP)
.pollEnrich().simple("{{URL_CORRELATIVO}}?ruta=STEP", String.class).aggregationStrategy(new EstrategiaCorrelativo()).cacheSize(1).timeout(10000).aggregateOnException(true)
.to(URI_TOPIC_ARTICULOS);
or with a ProducerTemplate inside a processor:
final String URL = exchange.getContext().resolvePropertyPlaceholders("{{URL_PAGO}}");
ProducerTemplate producer = exchange.getContext().createProducerTemplate();
String response = producer.requestBody(URL, "", String.class);
producer.stop();
So, as you can see, I'm doing nothing too complicated.
What could be causing the problem?
Ok... I solved the problem. It was a thing between camel parameters and http parameters.
First: Actually, I was using the http4 component like this:
String URL = exchange.getContext().resolvePropertyPlaceholders("{{URL_PAGO}}");
String PARAMS = "?param1=" + value1 + "¶m2=" + value2;
ProducerTemplate producer = exchange.getContext().createProducerTemplate();
String response = producer.requestBody(URL + PARAMS, "", String.class);
producer.stop();
I did it that way because the documentation says it:
The camel-http4 producer supports URI parameters to be sent to the HTTP server. The URI parameters can either be set directly on the endpoint URI or as a header with the key Exchange.HTTP_QUERY on the message:
But... If value1 and/or value2 change, camel will use URL + PARAMS to create a NEW endpoint. So, if I use that code a million of times, it will create a million of http4 endpoints with all the stuff (headers, caché, etc).
To avoid that I use the Exchange.HTTP_QUERY header:
String URL = exchange.getContext().resolvePropertyPlaceholders("{{URL_PAGO}}");
String PARAMS = "param1=" + value1 + "¶m2=" + value2;
Map<String,Object> headers = new HashMap<String,Object>();
headers.put(Exchange.HTTP_QUERY, PARAMS);
ProducerTemplate producer = exchange.getContext().createProducerTemplate();
String response = producer.requestBody(URL, "",headers, String.class);
producer.stop();
using this method, camel creates only 1 http4 endpoint.
I think the documentation should be more detailed about this point.
Bye.