【发布时间】:2018-08-10 14:08:29
【问题描述】:
我使用具有类 LDAPConnection 的 Unbound ID 库,该类没有默认构造函数并实现 LDAPInterface。我按如下方式生成 LDAPConnection:
@Produces
@SimpleLdapConnection
@ApplicationScoped
public LDAPInterface createLdapConnection() throws GeneralSecurityException, LDAPException {
LDAPConnection conn = new LDAPConnection(host, port, username, password);
return conn;
}
我现在想将此 LDAPConnection 类注入第二个生产者,它应该生成一个连接池:
@Inject
@SimpleLdapConnection
LDAPInterface simpleLdapConnection;
@Produces
@Default
@ApplicationScoped
public LDAPInterface produceLdapConnectionPool() throws GeneralSecurityException, LDAPException {
LDAPConnectionPool pool = new LDAPConnectionPool((LDAPConnection)simpleLdapConnection.g, connectionPoolInitialSize, connectionPoolMaxSize);
return pool;
}
要创建 LDAPConnectionPool,我需要将 simpleLdapConnection 转换为 LDAPConnection(因为它必须是 LDAPConnection)。
但是,我得到了错误:
java.lang.ClassCastException: org.jboss.weld.proxies.LDAPInterface$1687649628$Proxy$_$$_WeldClientProxy 无法转换为 com.unboundid.ldap.sdk.LDAPConnection
在 at.rsg.lp.benutzerverwaltung.business.repository.LdapConnectionPoolProvider.produceLdapConnectionPool(LdapConnectionPoolProvider.java:59)
如何解决此错误? 附言更改第一个生产者以返回 LDAPConnection 不起作用,因为我收到错误“Injected normal scoped bean is not proxyable”。
【问题讨论】:
-
问题似乎是由于 LDAPConnection 是最终的。这迫使 Weld 创建这样的代理。一个(尽管丑陋的)解决方案是编写一个非最终包装类。
-
您真的需要将
LDAPConnection公开为 CDI bean 吗?如果不是,您可以简单地将其存在隐藏在produceLdapConnectionPool()中,即new LDAPConnection(...)出现在该方法中,您使用局部变量创建LDAPConnectionPool并忘记它。 -
多考虑一下你提到的包装器,这当然是一个可行的解决方案,毕竟可能不会那么难看。实际上,在 Unbound ID API 之上创建对象的“包装器”layer 可能是一个好主意,它将您的实现与它分离,甚至可能产生更多好处,例如可测试性/模拟能力。当然是以更多代码为代价的。
-
将
LDAPConnection公开为 bean 并不是真正必要的,但是在使用produceLdapConnectionPool 时我遇到了类似的问题。有理由我也需要转换为那个,然后再次发生这样的异常。所以包装器可能是要走的路......
标签: cdi weld unboundid-ldap-sdk