Currently I developed a JCA outbound adapter (with LocalTransaction support) and I've got some troubles with connection management. My adapter works well, except the server (WebLogic 12c) does not put the ManagedConnections back to the pool. According to JavaDoc, the server must call ManagedConnection.cleanup()
to reinitialize the connection and put it back to the pool, but it does not.
When I use the adapter from EJB, the server creates a new ManagedConnection, begins a new transaction, commits it, but does not call the ManagedConnection.cleanup()
method and does not put it back to the pool.
Below you can see my testing bean:
@Stateless(mappedName = "TestingBean")
@Local(value = TestingBeanLocal.class)
@Remote(value = TestingBeanRemote.class)
@TransactionManagement(value = TransactionManagementType.CONTAINER)
@TransactionAttribute(value = TransactionAttributeType.REQUIRES_NEW)
public class TestingBean implements TestingBeanCommon{
@Resource(mappedName = "eis/myJCA")
private MyDataSource dataSource;
@Override
public void performTestAction(String param1, String param2) {
MyConnection connection = dataSource.getMyConnection();
connection.performAction(ActionFactory.getSomeAction(param1, param2));
}
}
After 10 invocations I get the following:
Got Initial context javax.ejb.EJBException: EJB Exception: ; nested exception is: java.lang.RuntimeException: javax.resource.spi.ApplicationServerInternalException: Unable to get a connection for pool = "eis/myJCA", weblogic.common.resourcepool.ResourceLimitException: Configured maximum limit of (0) on number of threads allowed to wait for a resource reached for pool eis/myJCA
As you noticed, it uses a new transaction for each invocation (REQUIRES_NEW
attribute). The Server creates a new ManagedConnection instance first 10 times and then the connection pool reaches its maximal capacity.
It is clear from tracing the logs that no single call of ManagedConnection.cleanup()
occurs and every connection in the pool is busy. I've read the JCA spec and discovered that the adapter can send lifecycle events to listeners using callback functions, but any attempt to use those event listeners callbacks ended with a new Exception:
javax.ejb.EJBException: BEA1-001471C1E76DE5A4E067; nested exception is: weblogic.transaction.nonxa.NonXAException: java.lang.IllegalStateException: [Connector:199175]This ManagedConnection is managed by a container for its transactional behavior and has been enlisted to a JTA transaction by a container; application/adapter must not call the local transaction begin/commit/rollback API. Reject event LOCAL_TRANSACTION_COMMITTED from adapter. javax.ejb.EJBException: EJB Exception: ; nested exception is: java.lang.IllegalStateException: [Connector:199175] This ManagedConnection is managed by a container for its transactional behavior and has been enlisted to a JTA transaction by a container; application/adapter must not call the local transaction begin/commit/rollback API. Reject event LOCAL_TRANSACTION_ROLLEDBACK from adapter.
I suppose WebLogic does not wait for any event (maybe I've sent the wrong one?).
So, what am I doing wrong? How to make the server put connections back to the pool?
UPD: I discovered that connection events are very important to the server. A server manages connections based on events info, that were send to listeners, which it registers to ManagedConnection. Now I supported events in my adapter, but WebLogic still does not want to put connections back to the pool. Currently I get following events in logs:
- LOCAL_TRANSACTION_STARTED
- CONNECTION_CLOSED
- LOCAL_TRANSACTION_COMMITTED
It looks fine for me (the CONNECTION_CLOSED event means application closed the connection, I added close method, that sends this event). Commit successful and no Exceptions appears. It seems that I've sent events in right order (earlier WebLogic throws Exceptions, but now stops doing it), but the server still does not put connections back to the pool.
I am confused.
close()
onconnection
(if implemented)? Connection based JCA APIs typically require this. Off topic, but you can omit@TransactionManagement
and most likely themappedName
. The first is the default and the second rarely needed. – Arjan Tijmsclose()
method. What this method should do? I've seen close method in JCA file adapter example,where this method just sends theCONNECTION_CLOSED
event to listeners, but WebLogic does not wait for events... BTW, I completely agree with you aboutmappedName
and@TransactionManagement
attribute. – gkuzmin