Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java EE (J2EE) и Spring > slf4j static linking


Автор: gelo86 26.3.2010, 00:19
Многие столкнулись с проблемой commons-logging и log4j в tomcat. Проблемы проицходят изза class loader'ов (http://articles.qos.ch/classloader.html). Есть такая штука как slf4j. Она типа ресолвит логгеры статически (static linking). Так вот вопрос, что имеется в виду как говорится о static linking ?

Автор: jk1 26.3.2010, 09:13
Цитата

Slf4j uses static linking: one simply select a jar, and sticks it into the classpath - there are a bunch of such jars available. Commons logging uses runtime dynamic classloader lookups. The latter, "clogging", is prone to devious problems when being used with intense classloader-rich systems, like a servlet container (not relevant here), or in an OSGi environment (very relevant). SLF4j was created to overcome this problem by simply being statically linked.


Под static linking понимается тот факт, что будет использован тот логгер, который вы положите в CLASSPATH. Если там лежит slf-simple, то вы получите вывод в System.out, если slf-log4j, то будет использован log4j и т. д.

Автор: gelo86 27.3.2010, 12:53
Да но, если будет использоватся log4j, то почему теряется проблема classloaderа ? log4j как я понимаю дальше будет загружатся как обычно. Да и при том если не испльзовать slf, то ведь все джары тоже в CLASSPATH лежат, но потом оказывается что есть проблемы с classloaderми.

Автор: jk1 30.3.2010, 17:21
Цитата

то почему теряется проблема classloaderа ? 

потому что самого log4j (для примера) в CLASSPATH может и не быть, а если он будет, то абсолютно неважно какой он был загружен динамически. На самом деле логгирование будут осуществлять классы slf4j-log4j с использованием предложенного log4j конфига.

На самом деле это оказалось не так, см. пост ниже

Автор: gelo86 1.4.2010, 21:50
разве будет исполнаться логгированиэ если в CLASSPATH небудет log4.jar ? в самом slf4j нету ведь парсера log4j конфига да и инициализатора, там толка так сказать адаптары к другому фрамеворку по логировании.

Автор: jk1 1.4.2010, 23:36
Цитата

разве будет исполнаться логгированиэ если в CLASSPATH небудет log4.jar

Действительно, я был неправ.

Вопрос оказался весьма интересным и вот что удалось найти:

Как известно, полиморфизм в Java реализован посредством позднего или, как иногда пишут, dynamic-связывания. На нем работает и JCL, получая полный спектр описанных проблем с ClassLoader'ами:
Цитата

If commons-logging.jar is in the system classpath in a J2EE environment, the "current" or "thread context" classloader for each individual webapp contains WEB-INF/lib, but commons-logging itself is loaded in the system (parent) classpath. commons-logging looks for log4j using the thread-context classloader and therefore will "see" log4j in WEB-INF/lib, but tries to actually load it in the system classpath, and breaks with a NoClassDefFoundError. 

Происходит это потому, что на этапе компиляции невозможно однозначно разрешить вызовы переходников от JCL к конкретным логгерам такого вида:
Код

LogFactory.getLog("logger.name.not.important.here");
 
В отличие от JCL, SLF4J вызывает статические методы своих переходников, таких как slf4j-log4j, а эти вызовы могут быть разрешены уже на этапе компиляции. Единственное, что остается прояснить, так это как удается использовать разные логгеры при связях на статике. Для этого SLF-api компилируется вместе с классом-затычкой StaticLoggerBinder, который не входит потом в slf4j-api.jar. Вместо этого во время выполнения используется аналогичный по названию, но разный по содержанию StaticLoggerBinder конкретного переходника. И раз вызовы API разрешены на этапе компиляции, то никакие загрузчики классов не участвуют в привязке API к конкретному логгеру.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)