Получение Spring Error «Bean с именем« x »должен иметь тип [y], но был фактически типом [$ Proxy]» в Jenkins

18

Я отлаживал это некоторое время, и я надеюсь, что кто-то может пролить свет здесь.

У меня есть проект Maven, который добавлен в Jenkins, используя JDK 1.6. Я использую AOP в этом проекте для обработки транзакции базы данных.

Когда я запускаю сборку в Jenkins, мой тестовый файл не работает со следующими исключениями: -

Caused by: org.springframework.beans.factory.BeanCreationException: 
Error creating bean with name 'dataHandlerClassificationImpl': 
Injection of resource dependencies failed; nested exception is 
org.springframework.beans.factory.BeanNotOfRequiredTypeException: 
Bean named 'writerDataLocationImpl' must be of type [xxx.script.WriterData], 
but was actually of type [$Proxy17]
    ...
    ...
Caused by: org.springframework.beans.factory.BeanNotOfRequiredTypeException: 
Bean named 'writerDataLocationImpl' must be of type [xxx.script.WriterData], 
but was actually of type [$Proxy17]
    ...
    ...

Класс DataHandlerClassificationImpl выглядит примерно так: -

@Service
public class DataHandlerClassificationImpl extends DataHandler {

    @Resource(name="writerDataLocationImpl")
    private WriterData writerData;

    ...
}       

WriterData - это интерфейс с несколькими реализациями.

Я могу выполнить код без проблем из IDE. Чтобы определить, является ли это проблемой Maven или проблемой Jenkins, я перешел к папке заданий проекта Jenkins с помощью командной строки, и я могу запустить mvn test без каких-либо ошибок.

Я знаю, что прокси-ошибка имеет какое-то отношение к AOP, и что я могу только autwire для интерфейса вместо конкретного класса ... но это не так, поскольку я могу запустить мой код отлично за пределами Jenkins .

Любые идеи? Благодарю.     

задан limc 05.12.2011 в 22:12
источник
  • Вы работаете на Cobertura, Sonar или другом инструменте для кодирования кода на Jenkins? Что такое команда mvn build? Можете ли вы попробовать заменить инъецированную подачу на частный Object writerData и dump writerData.getClass (). GetInterfaces после обработки ошибок компиляции? Это может дать нам понять, какова природа этого нежелательного и странного прокси. –  Tomasz Nurkiewicz 05.12.2011 в 22:18
  • Под «Целями и параметрами Дженкинса» у меня был чистый коберрура: сайт cobertura. Просто ради моего любопытства, я изменил его, чтобы очистить тест, и он работал нормально. Когда я изменил его на чистый сайт, я снова получаю такое же исключение. Похоже, что это как-то связано с сайтом. Есть идеи? Благодарю. –  limc 05.12.2011 в 22:27
  • @Thomasz, как именно я сбрасываю writerData.getClass (). getInterfaces? Intellij в основном дает мне регулярную ошибку компиляции. –  limc 05.12.2011 в 22:30
  • Это определенно связано с сайтом mvn. Я запустил эту команду из командной строки, и я получаю точное исключение. Я не уверен, почему это ведет себя иначе, чем тест. –  limc 05.12.2011 в 22:33
  • Попробуйте следующее: Arrays.asList (new Object (). getClass (). getInterfaces ()) в afterPropertiesSet или @PostConstruct. Я немного удивлен тем, что сайт вызывает эту проблему, поскольку я знаю, что Cobertura / Sonar имеют тенденцию вводить эту ошибку. Можете ли вы попробовать mvn cobertura: cobertura в одиночку? Должен потерпеть неудачу ... –  Tomasz Nurkiewicz 05.12.2011 в 22:35
Показать остальные комментарии

1 ответ

42

Выдержка из комментариев:

Вы используете Cobertura, Sonar или другой инструмент для кодирования кода на Jenkins? Обратите внимание, что mvn site также может быть настроено для включения отчета Cobertura в сгенерированном site .

Проблема с Cobertura заключается в том, что она выполняет довольно тяжелую байтовую систему, включая добавление некоторых пользовательских интерфейсов. Когда Spring запускается, он генерирует прокси-серверы для боба. Если bean имеет хотя бы один интерфейс, он использует стандартный Java-прокси. В противном случае он пытается создать прокси класса.

Я предполагаю, что в вашем случае использовался прокси-сервер класса CGLIB, но после того, как утилита Cobertura Spring вернулась к java-прокси. Это вызвало ошибку при запуске, поскольку ожидаемый класс впрыска ожидаемого класса (или подкласс CGLIB).

Чтобы сократить длинную историю, запустите прокси-сервер класса CGLIB, и все будет хорошо:

<aop:config proxy-target-class="true"/>
    
ответ дан Tomasz Nurkiewicz 05.12.2011 в 23:27
источник
  • Ты потрясающий Томаш :-) Ваше объяснение помогло мне. –  K. Siva Prasad Reddy 18.05.2012 в 13:50
  • Что такое пространство имен для aop? –  Christian Schlichtherle 01.08.2016 в 14:26
  • xmlns: aop="springframework.org/schema/aop&quot; –  Raja Anbazhagan 20.06.2017 в 20:27
  • Это свойство весной загрузки - spring.aop.proxy-target-class = true –  Vikky 14.02.2018 в 21:26