Spring WebApplicationInitializer (ServletContainerInitializer, @HandlesTypes) со встроенным Tomcat

Я не понимаю, почему в следующем минимальном проекте моя реализация интерфейса Spring WebApplicationInitializer обнаруживается при выполнении тестов в Eclipse и IntelliJ, но не при использовании Maven (mvn clean test).

С Eclipse и IntelIJ я вижу INFO: Spring WebApplicationInitializers detected on classpath: [com.example.pack.DummyInitializer@26d678a4]

С mvn clean test я вижу INFO: No Spring WebApplicationInitializer types detected on classpath.

В тесте я запускаю Embedded Tomcat:

String pathToWebXML = new File("src/main/webapp/").getAbsolutePath();
tomcat = new Tomcat();
tomcat.setBaseDir("embedded_tomcat");
tomcat.setPort(0);
tomcat.addWebapp("", pathToWebXML);
tomcat.start();

web.xml ссылается на реализацию ServletContextListener, которая создает новую (и пустую) AnnotationConfigWebApplicationContext.

Я загрузил пример проекта на GitHub: https://github.com/C-Otto/webapplicationinitializer


person C-Otto    schedule 06.05.2016    source источник
comment
Какую версию Java вы используете в IntelliJ. Вы используете java 8? Я заметил, что в файле pom вы используете java 8   -  person Periklis Douvitsas    schedule 11.05.2016
comment
@Periklis Да, я использую Java 8. Вы видели намек на то, что я не использую Java 8? Я запутался в вашем вопросе.   -  person C-Otto    schedule 11.05.2016
comment
Извините за путаницу, я просто хотел убедиться, что версия Java, которую вы используете в IntelliJ, является той же версией, которую вы определили в pom.xml. Всякий раз, когда у меня будет время, я загружу ваше приложение и попробую   -  person Periklis Douvitsas    schedule 11.05.2016
comment
ХОРОШО. Насколько я знаю, IntelIJ автоматически импортирует настройки Maven (включая версию Java).   -  person C-Otto    schedule 11.05.2016
comment
Дизайнерское решение связано со Spring Boot, которым я не пользуюсь. Тем не менее, упомянутая проблема Tomcat является проницательной. На основе bz.apache.org/bugzilla/show_bug.cgi?id= 52853#c19 вы видите способ заставить Tomcat правильно находить/сканировать/... в случае с Maven?   -  person C-Otto    schedule 11.05.2016
comment
Я только что узнал, что установка useSystemClassLoader на false в конфигурации Surefire решает эту конкретную проблему. Однако я не до конца понимаю последствия и был бы признателен за объяснение рассматриваемой проблемы. См. также maven.apache.org/surefire/maven- surefire-плагин/примеры/   -  person C-Otto    schedule 12.05.2016
comment
В качестве альтернативы помогает отключить useManfestOnlyJar. Тем не менее, это то, что я не понимаю. Я дам вознаграждение любому, кто объяснит это, см. bugs.eclipse.org /bugs/show_bug.cgi?id=447790 :)   -  person C-Otto    schedule 12.05.2016


Ответы (2)


Как указано в комментариях, путь к классам, используемый Maven Surefire (и Maven Failsafe) в настройках по умолчанию, не сканируется Tomcat. На большинство классов ссылаются с помощью файла MANIFEST.MF внутри файла JAR.

Один из вариантов — отключить настройку useSystemClassLoader плагинов Maven. Однако при этом изменяются детали загрузчика классов, что может вызвать другие проблемы.

В качестве другого варианта можно отключить useManifestOnlyJar, что может вызвать проблемы на компьютере с Windows.

В нашем проекте мы решили удалить классы-инициализаторы и вместо этого зарегистрировать все, что они должны были делать, вручную. В конкретном примере, поскольку наша реализация AbstractSecurityWebApplicationInitializer не была найдена, теперь мы регистрируем фильтр безопасности вручную внутри метода contextInitialized:

String filterName = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME);
servletContext.addFilter(filterName, new DelegatingFilterProxy(filterName)).addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), false, "/*");
person C-Otto    schedule 24.05.2016
comment
Другой вариант — сделать так, чтобы Tomcat также включал банки, на которые ссылается файл манифеста, в банку, созданную surefire. Это можно сделать в context.xml, установив для атрибута ScanManifest Jar Scanner значение true. - person user1304680; 16.01.2017

Вы можете указать Tomcat включить банки, на которые ссылается файл манифеста, в банку, созданную surefire. Это можно сделать, context.xml установив для атрибута Jar Scanner scanManifest значение true. Это значение по умолчанию в новых версиях Tomcat, как указано здесь: https://bz.apache.org/bugzilla/show_bug.cgi?id=59961.

person user1304680    schedule 16.01.2017