Weldclientproxy не может быть приведен

Я использую библиотеку Unbound ID с классом LDAPConnection, у которого нет конструктора по умолчанию и который реализует 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 cannot be cast to com.unboundid.ldap.sdk.LDAPConnection

at at.rsg.lp.benutzerverwaltung.business.repository.LdapConnectionPoolProvider.produceLdapConnectionPool(LdapConnectionPoolProvider.java:59)

Как мне обойти эту ошибку? P.S. изменение первого производителя для возврата LDAPConnection не работает, поскольку я получаю сообщение об ошибке «Введенный компонент с нормальной областью видимости не является прокси-сервером».

Проблема, похоже, вызвана тем, что LDAPConnection является окончательным. Это заставляет Weld создать такой прокси. Одно (хотя и уродливое) решение - написать неокончательный класс-оболочку.

stefan.m 10.08.2018 16:43

Вам действительно нужен LDAPConnection, представленный как bean-компонент CDI? Если нет, вы можете просто скрыть его существование в produceLdapConnectionPool(), то есть new LDAPConnection(...) возникает в этом методе, вы используете локальную переменную для создания LDAPConnectionPool и забываете о нем.

Nikos Paraskevopoulos 10.08.2018 17:00

Если подумать, то упомянутая вами оболочка, которая, конечно, является жизнеспособным решением, в конце концов может оказаться не таким уж уродливым. Фактически, создание «оболочки» слой объектов поверх Unbound ID API может быть хорошей идеей, которая отделит вашу реализацию от него и может даже принести больше преимуществ, например возможность тестирования / имитация. Конечно, ценой большего количества кода.

Nikos Paraskevopoulos 10.08.2018 17:13

Раскрытие LDAPConnection как bean-компонента на самом деле не обязательно, но затем я сталкиваюсь с аналогичной проблемой при использовании produLdapConnectionPool. Есть причина, по которой мне тоже нужно выполнить приведение к этому, а затем снова возникает такое исключение. Так что обертка, вероятно, лучший вариант ...

stefan.m 10.08.2018 17:22
0
4
582
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

С точки зрения CDI, вы сталкиваетесь с определенными типами bean-компонентов для метода производителя. Это поддерживается Спецификация CDI.

Короче говоря, для методов-производителей типы bean-компонентов являются производными от возвращаемых типов и интерфейсов, которые он реализует. Например. фактический тип реализации - нет включен. Причина в том, что вы видите, когда пытались вернуть фактический тип реализации - impls часто содержат методы final или другие неровности, делающие их непроверенный.

Есть две вещи, которые я могу придумать, чтобы решить эту проблему:

  1. [Этот, скорее всего, потерпит неудачу] Попробуйте наложить аннотацию @Typed на вашего продюсера - я сомневаюсь, что это сработает в этом случае, но, возможно, стоит попробовать. Эта аннотация объявляет все типы, которые будет иметь компонент. Вы бы использовали его так - @Typed({LDAPInterface, LDAPConnection}).
  2. [Это должен быть вариант] На вашем месте я бы создал объект-оболочку, как вы предложили. На самом деле это не будет так уж уродливо, всего несколько кусочков кода должны помочь.

1) звучит как хорошая идея, но, как вы предположили, не работает (возникает то же исключение ClassCastException). 2) работает конечно.

stefan.m 13.08.2018 12:41

Другие вопросы по теме