Search code examples
javaglassfishglassfish-4jca

GlassFish randomly selects wrong JCA ConnectionFactory for Injection


I am in the process of writing a JCA Resource Adapter for FTP and SFTP. As my goal is to be able to use one protocol completely independent from the other, I have two different ManagedConnectionFactory classes, one for each protocol. Both have different ConnectionDefinition annotations; the Glassfish domain.xml contains a resource definition for the FTP Adapter but not for the SFTP Adapter. Now, when I inject the FTPConnectionFactory into an EJB, I sometimes get an InjectionException as WELD tries to inject the SFTPConnectionFactory instead (this is of course consistent during a run of the appserver; I either consistently get the right or the wrong one). Removing the ConnectionDefinition annotation for the SFTP adapter seems to fix the problem.

So, Questions:

  • How can I fix this and make Glassfish inject the correct class? Can this be caused by a problem in my code or is this a Glassfish issue?
  • According to the spec it is legal for a RA to have multiple ConnectionDefinition annotations, as well as multiple instances of a class implementing ManagedConnectionFactory; but I couldn't find any information about having multiple different classes implementing ManagedConnectionFactory inside of the same Resource Adapter. Glassfish clearly seems to have a problem with it - is this explicitly allowed or disallowed somewhere?

The ConnectionDefinition (with FTP replaced by SFTP for the SFTP case):

@ConnectionDefinition(connectionFactory = FTPConnectionFactory.class,
    connectionFactoryImpl = FTPConnectionFactoryImpl.class,
    connection = FTPConnection.class, connectionImpl = FTPConnectionImpl.class)

The FTP and SFTP Factory and ManagedConnection classes share common ancestors but are not directly related - but this doesn't seem to matter as completely separating the implementations makes no difference.

The domain.xml snippet:

<resource-adapter-config resource-adapter-name="ftpconnector" thread-pool-ids="thread-pool-1" />
<connector-connection-pool name="jca/ftpConnectorPool"
    resource-adapter-name="ftpconnector"
    connection-definition-name="foo.bar.ftp.FTPConnection"
    transaction-support="NoTransaction" match-connections="false" />
<connector-resource pool-name="jca/ftpConnectorPool" jndi-name="jca/ftpConnector" />

And the injected field:

@Resource(lookup = "jca/ftpConnector")
private FTPConnectionFactory ftpConnectionFactory;

Solution

  • TL;DR: This was caused by an incorrectly configured Connection Pool, where connection-definition-name does not point to a class implementing ConnectionFactory. The observed behaviour is IMO a bug and has been reported here.


    While trying to reproduce this issue with Adam Biens connectorz Filesystem Resource Adapter (by adding a second set of classes and another connection definition), I found I could only reproduce the behaviour if the connector-connection-pool in the domain.xml is incorrectly defined: If I changed the connection-definition-name to point to a nonexistent class, Glassfish would randomly take one of the two defined connectors. Doublechecking my Connection Pool, I found out that I mistakenly used the Connection class instead of the ConnectionFactory class in the xml. So when the attribute does not point to a class implementing the ConnectionFactory interface, Glassfish seems to randomly choose any class from the Resource Adapter which implements ConnectionFactory, without even printing an error message.