Как подавить SLF4J Предупреждение о множественных привязках? - PullRequest
14 голосов
/ 27 сентября 2011

Мой Java-проект зависит от разных версий SLF4J.Как я подавляю раздражающие предупреждения?

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:xyz234/lib/slf4j-
log4j12-1.5.8.jar!/org/slf4j/impl/StaticLoggerBinder.class]

SLF4J: Found binding in [jar:file:xyz123/.m2/repository/org/slf4j/slf4j-log4j12
/1.6.0/slf4j-log4j12-1.6.0.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.

PS: Это не тот же вопрос, что и slf4j, предупреждающий о том, что одна и та же привязка дублируется , ответ на этот вопрос - как избавиться отпредупреждение о ложной тревоге, но в моем случае это истинное предупреждение.PSS: Извините, я забыл упомянуть: я использую Maven и SLF4J включен в зависимости моих зависимостей.

Ответы [ 6 ]

20 голосов
/ 27 сентября 2011

Удалите один из slf4j-log4j12-1.5.8.jar или slf4j-log4j12-1.6.0.jar из пути к классам. Ваш проект не должен зависеть от разных версий SLF4J. Я предлагаю вам использовать только 1.6.0.

Если вы используете Maven, вы можете исключить переходные зависимости . Вот пример:

<dependency>
    <groupId>com.sun.xml.stream</groupId>
    <artifactId>sjsxp</artifactId>
    <version>1.0.1</version>
    <exclusions>
        <exclusion>
            <groupId>javax.xml.stream</groupId>
            <artifactId>stax-api</artifactId>
        </exclusion>
    </exclusions>
</dependency>

В текущей реализации slf4j-api удалить эти предупреждения невозможно. Класс org.slf4j.LoggerFactory печатает сообщения:

  ...
  if (implementationSet.size() > 1) {
    Util.report("Class path contains multiple SLF4J bindings.");
    Iterator iterator = implementationSet.iterator();
    while(iterator.hasNext()) {
      URL path = (URL) iterator.next();
      Util.report("Found binding in [" + path + "]");
    }
    Util.report("See " + MULTIPLE_BINDINGS_URL + " for an explanation.");
  }
  ...

Класс Util имеет следующий вид:

public class Util {

  static final public void report(String msg, Throwable t) {
    System.err.println(msg);
    System.err.println("Reported exception:");
    t.printStackTrace();
  }
  ...

Метод report записывает непосредственно в System.err. Обходным путем может быть замена System.err на System.setErr() до первого LoggerFactory.getLogger() вызова, но вы можете потерять другие важные сообщения, если вы сделаете это.

Конечно, вы можете скачать исходный код и удалить эти Util.report вызовы и использовать ваш измененный slf4j-api в вашем проекте.

5 голосов
/ 27 сентября 2011

Читали ли вы URL, на который ссылается предупреждение?

SLF4J: See [http://www.slf4j.org/codes.html#multiple_bindings][1] for an explanation.

Вот что говорит ссылка:

SLF4J API предназначен для связывания с одним и только одним базовымрамки ведения журнала одновременно.Если в пути к классу присутствует более одной привязки, SLF4J выдаст предупреждение с указанием расположения этих привязок.Когда это происходит, выберите одну и только одну привязку, которую вы хотите использовать, и удалите другие привязки.

Например, если у вас есть оба slf4j-simple-1.6.2.jar и slf4j-nop-1.6.2.jar на пути к классам, и вы хотите использовать привязку nop (без операций), а затем удалить slf4j-simple-1.6.2.jar из пути к классам.

Обратите внимание, что предупреждение отправляетсяSLF4J это просто предупреждение.SLF4J будет по-прежнему связываться с первым каркасом, который он найдет в пути к классам.

3 голосов
/ 20 июня 2014
    PrintStream filterOut = new PrintStream(System.err) {
        public void println(String l) {
            if (! l.startsWith("SLF4J")) {
                super.println(l);
            }
        }
    };
    System.setErr(filterOut);

et voilà!

1 голос
/ 27 марта 2019

Иногда исключение 2-го регистратора из пути к классам требует слишком большого количества искажений, и предупреждение невероятно раздражает.Маскировка стандартной ошибки как самого начала программы, кажется, работает, например,

    public static void main(String[] args)
    {
        org.apache.log4j.Logger.getRootLogger().setLevel(org.apache.log4j.Level.OFF);
        PrintStream old = System.err;
        System.setErr(new PrintStream(new ByteArrayOutputStream()));
        // ... trigger it ...
        System.setErr(old);

        ...

, в результате чего часть trigger it должна вызвать некоторую функцию nop, которая обращается к системе регистрации и в противном случае вызвала бы сообщениечтобы быть сгенерированным.

Я бы не рекомендовал это для производственного кода, но для целей skunkworks это должно помочь.

1 голос
/ 07 октября 2015

Если используется maven, всегда используйте команду

mvn dependency:tree

В этом списке будут перечислены все зависимости, добавленные в проект, включая зависимости от включенных нами jar.Здесь мы можем указать несколько версий или несколько копий банок, которые входят с другими банками, которые были добавлены.Используйте

<exclusions><exclusion><groupId></groupId><artifactId></artifactId></exclusion></exclusions>

в элементе <dependency>, чтобы исключить конфликтующие элементы.Всегда повторяйте команду maven выше после каждого исключения, если проблема не устранена.

0 голосов
/ 05 февраля 2013

Если вы используете старую версию Jetty (скажем, Jetty 6), вам может потребоваться изменить порядок загрузки классов для веб-приложения, чтобы сделать его более приоритетным, чем контейнер.Вы можете сделать это, добавив эту строку в XML-файл контейнера:

<Set name="parentLoaderPriority">false</Set>
...