Разработал приложение в связке Wicket+Hibernate. Wicket использует SLF4J, который я перенаправил на Log4J, положив в каталог с библиотеками файл slf4j-log4j12-1.5.11.jar. Встроил в приложение Jetty 6.1. При запуске получаю ошибку:
SLF4J: Class path contains multiple SLF4J bindings.
Совершенно точно никаких других bindings для SLF4J в приложении нет. Через Resin/Tomcat то же самое приложение стартует на ура, а вот с Jetty — облом. Полагаю, проблема именно в Jetty, которая умудряется classpath составить таким образом, что slf4j-log4j12-1.5.11.jar попадает в него дважды.
Есть идеи по поводу решения проблемы?
Re: Jetty и SLF4J: Class path contains multiple SLF4J bindin
Здравствуйте, slskor, Вы писали:
S>SLF4J: Class path contains multiple SLF4J bindings.
S>Совершенно точно никаких других bindings для SLF4J в приложении нет.
Абсолютно уверены?
Я не поленился, скачал Jetty 6.1.25. Директория lib/jsp-2.0. Файлы slf4j-api-1.3.1.jar и slf4j-simple-1.3.1.jar Вам о чем-нибудь говорят?
Здравствуйте, Skipy, Вы писали:
S>Я не поленился, скачал Jetty 6.1.25. Директория lib/jsp-2.0. Файлы slf4j-api-1.3.1.jar и slf4j-simple-1.3.1.jar Вам о чем-нибудь говорят?
Jetty используется как embedded server. Из всего сервера я взял только jetty-6.1.25.jar и jetty-util-6.1.25.jar. Каталога lib/jsp-2.0 нету в принципе.
Re[3]: Jetty и SLF4J: Class path contains multiple SLF4J bin
Здравствуйте, slskor, Вы писали:
S>Здравствуйте, Skipy, Вы писали:
S>>Я не поленился, скачал Jetty 6.1.25. Директория lib/jsp-2.0. Файлы slf4j-api-1.3.1.jar и slf4j-simple-1.3.1.jar Вам о чем-нибудь говорят?
S>Jetty используется как embedded server. Из всего сервера я взял только jetty-6.1.25.jar и jetty-util-6.1.25.jar. Каталога lib/jsp-2.0 нету в принципе.
Я Вам один умный вещь скажу, но Вы не обижайтесь. Повторное включение одного и того же архива в classpath не приводит к такому эффекту. Специально проверил. А вот включение двух разных, но содержащих один и тот же класс, — приводит. Я взял slf4j-log4j12-1.5.11.jar и slf4j-simple-1.5.11.jar и прогнал на них код, который работает внутри SLF4J API. Если включить два раза только первый архив, он находит один класс, если оба — два. Так что... В общем, ищите, откуда у Вас в classpath попадает еще один экземпляр реализации slf4j.
Здравствуйте, Skipy, Вы писали:
S>Здравствуйте, slskor, Вы писали:
S>>Здравствуйте, Skipy, Вы писали:
S>>>Я не поленился, скачал Jetty 6.1.25. Директория lib/jsp-2.0. Файлы slf4j-api-1.3.1.jar и slf4j-simple-1.3.1.jar Вам о чем-нибудь говорят?
S>>Jetty используется как embedded server. Из всего сервера я взял только jetty-6.1.25.jar и jetty-util-6.1.25.jar. Каталога lib/jsp-2.0 нету в принципе.
S>Я Вам один умный вещь скажу, но Вы не обижайтесь. Повторное включение одного и того же архива в classpath не приводит к такому эффекту. Специально проверил. А вот включение двух разных, но содержащих один и тот же класс, — приводит. Я взял slf4j-log4j12-1.5.11.jar и slf4j-simple-1.5.11.jar и прогнал на них код, который работает внутри SLF4J API. Если включить два раза только первый архив, он находит один класс, если оба — два. Так что... В общем, ищите, откуда у Вас в classpath попадает еще один экземпляр реализации slf4j.
simple это такой же биндинг как и log4j. Добавьте его в excludes если пускаете мавеном и будет вам счастье
Re[4]: Jetty и SLF4J: Class path contains multiple SLF4J bin
Здравствуйте, Skipy, Вы писали:
S>>>Я не поленился, скачал Jetty 6.1.25. Директория lib/jsp-2.0. Файлы slf4j-api-1.3.1.jar и slf4j-simple-1.3.1.jar Вам о чем-нибудь говорят?
S>>Jetty используется как embedded server. Из всего сервера я взял только jetty-6.1.25.jar и jetty-util-6.1.25.jar. Каталога lib/jsp-2.0 нету в принципе.
S>Я Вам один умный вещь скажу, но Вы не обижайтесь. Повторное включение одного и того же архива в classpath не приводит к такому эффекту. Специально проверил. А вот включение двух разных, но содержащих один и тот же класс, — приводит. Я взял slf4j-log4j12-1.5.11.jar и slf4j-simple-1.5.11.jar и прогнал на них код, который работает внутри SLF4J API. Если включить два раза только первый архив, он находит один класс, если оба — два. Так что... В общем, ищите, откуда у Вас в classpath попадает еще один экземпляр реализации slf4j.
Стартовый класс упакован в jar, вот кусок манифеста:
Здравствуйте, Skipy, Вы писали:
S>>Jetty используется как embedded server. Из всего сервера я взял только jetty-6.1.25.jar и jetty-util-6.1.25.jar. Каталога lib/jsp-2.0 нету в принципе.
S>Я Вам один умный вещь скажу, но Вы не обижайтесь. Повторное включение одного и того же архива в classpath не приводит к такому эффекту.
Провел один эксперимент. Выяснилось, что проблема возникает, в тот момент, когда приложение, работающее под управлением Jetty, использует SLF4J. Сам Jetty тоже использует SLF4J. При этом Jetty очень хитро работает с классами из пакетов org.apache.commons.logging. org.apache.log4j. и org.slf4j. Подозреваю, он пытается изолировать логгеры, исползуемые приложениями. Но идеология bindings в SLF4J сильно этому мешает.
Re[4]: Jetty и SLF4J: Class path contains multiple SLF4J bin
Здравствуйте, Skipy, Вы писали:
S>>>Я не поленился, скачал Jetty 6.1.25. Директория lib/jsp-2.0. Файлы slf4j-api-1.3.1.jar и slf4j-simple-1.3.1.jar Вам о чем-нибудь говорят?
S>>Jetty используется как embedded server. Из всего сервера я взял только jetty-6.1.25.jar и jetty-util-6.1.25.jar. Каталога lib/jsp-2.0 нету в принципе.
S>Я Вам один умный вещь скажу, но Вы не обижайтесь. Повторное включение одного и того же архива в classpath не приводит к такому эффекту. Специально проверил. А вот включение двух разных, но содержащих один и тот же класс, — приводит.
Более детальное описание эксперимента. Встроил Jetty в приложение, которое запускает само себя как web-приложение под управлением Jetty. Вставил в web.xml тривиальнейший фильтр, который использует Log4J. Все в порядке. Заменил Log4J на SLF4J. И вот оно:
Первый биндер подключается через classpath при старте Jetty и нужен самому Jetty. Второй биндер подгружается при запуске web-приложения под управлением Jetty и он нужен приложению. Убрать ни тот, ни другой не получится, результатом будет что-то типа
И вот тут на меня напал тупняк. Чувствую, что решение должно быть примерно таким: Jetty должен предоставить свои логгеры и свой биндер в распоряжение запускаемого приложения. Но как это реализовать в случае с встроенным сервером? Знаний не хватает.
Re[4]: Jetty и SLF4J: Class path contains multiple SLF4J bin
Здравствуйте, Skipy, Вы писали:
S>Повторное включение одного и того же архива в classpath не приводит к такому эффекту. Специально проверил. А вот включение двух разных, но содержащих один и тот же класс, — приводит.
А вот в том-то и дело, что Class Loader в Jetty умудряется сделать "разными" даже файлы, загруженные из одного источника. Эксперимент такой: убираем биндер из каталога WEB-INF/lib но оставляем его в classpath. Разумеется, приложение без биндера SLF4J не запустится. Делаем хитрый финт:
WebAppContext context = new WebAppContext();
context.setContextPath("/");
context.setWar("bin");
context.setExtraClasspath("./lib2/slf4j-log4j12-1.5.8.jar");
Здесь в последней строке мы даем доступ к тому же самому биндеру, которые использует Jetty. Результат: