【问题标题】:WeldClientProxy cannot be castWeldClientProxy 无法强制转换
【发布时间】: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


【解决方案1】:

从 CDI 的角度来看,您遇到的是生产者方法的已定义 bean 类型。这是由CDI specification 支持的。

简而言之,对于生产者方法,bean 类型派生自返回类型及其实现的接口。例如。 包含实际的实现类型。原因正是您在尝试返回实际实现类型时所看到的 - 实现通常包含 final 方法或其他使它们成为 unproxyable 的颠簸。

我能想到两件事来解决这个问题:

  1. [这可能会失败] 尝试将@Typed 注释放在你的制作人身上——我怀疑它在这种情况下会起作用,但值得一试。这个注解声明了 bean 将拥有的所有类型。你会像这样使用它 - @Typed({LDAPInterface, LDAPConnection})
  2. [这应该是首选] 如果我是你,我会按照你的建议创建一个包装器对象。它不会真的那么难看,只需几段代码就可以了。

【讨论】:

  • 1) 听起来是个好主意,但正如您所假设的那样,它不起作用(发生相同的 ClassCastException)。 2) 当然可以。
猜你喜欢
  • 2018-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-17
  • 2019-03-11
相关资源
最近更新 更多