Как заставить Джерси использовать SLF4J вместо JUL? - PullRequest
23 голосов
/ 08 ноября 2010

Я нашел полезную статью , в которой объясняется, как заставить Джерси использовать SLF4J вместо JUL.Теперь мой модульный тест выглядит (и работает отлично):

public class FooTest extends JerseyTest {
  @BeforeClass
  public static void initLogger() {
    java.util.logging.Logger rootLogger =
      java.util.logging.LogManager.getLogManager().getLogger("");
    java.util.logging.Handler[] handlers = rootLogger.getHandlers();
    for (int i = 0; i < handlers.length; i++) {
      rootLogger.removeHandler(handlers[i]);
    }
    org.slf4j.bridge.SLF4JBridgeHandler.install();
  }
  public FooTest() {
    super("com.XXX");
  }
  @Test
  public void testSomething() throws Exception {
    // ...
  }
}

Мой pom.xml включает следующие зависимости:

<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-api</artifactId>
  <version>1.6.1</version>
</dependency>
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-log4j12</artifactId>
  <version>1.6.1</version>
</dependency>
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>jul-to-slf4j</artifactId>
  <version>1.6.1</version>
</dependency>
<dependency>
  <groupId>log4j</groupId>
  <artifactId>log4j</artifactId>
  <version>1.2.16</version>
</dependency>

Работает отлично, но я не хочусделать одну и ту же конфигурацию в каждом модульном тесте.Это очевидное дублирование кода, которого я хотел бы избежать.Как я могу сделать это более эффективно?

пс.Может быть, невозможно оптимизировать приведенный выше код, и я стараюсь изо всех сил?

Ответы [ 6 ]

17 голосов
/ 29 сентября 2014

Если вы используете клиентский API, вы можете вручную перенаправить журналы на slf4j (обратите внимание, что он может сломаться в будущих версиях, хотя это маловероятно):

Logger LOG = LoggerFactory.getLogger(MyClass.class); //slf4j logger

WebTarget ws = ClientBuilder.newClient(config)
                  .register(new LoggingFilter(new JulFacade(), true));

private static class JulFacade extends java.util.logging.Logger {
  JulFacade() { super("Jersey", null); }
  @Override public void info(String msg) { LOG.info(msg); }
}
5 голосов
/ 20 апреля 2011

Лучший способ сделать это через пользовательский Listener . Будучи инициализированным перед сервлетом JSF, он должен сконфигурировать мост jul-to-slf4j в contextInitialized(ServletContextEvent).

0 голосов
/ 20 марта 2018

Slf4jLogger из пакета org.apache.cxf:cxf-core - еще один вариант. Он реализует java.util.logging.Logger и делегирует cals для slf4J.

Сервер Джерси:

ResourceConfig config = new ResourceConfig(HelloWorldResource.class);
config.register(
    new Slf4jLogger(this.getClass().getName(), null));

Клиент Джерси:

ClientBuilder
    .newClient()
    .register(
        new LoggingFeature(
                new Slf4jLogger(this.getClass().getName(), null)));
0 голосов
/ 11 января 2018

Это сработало для меня:

public abstract class JerseyTestSFL4J extends JerseyTest {

  static {
    // Get JerseyTest to use SLF4J instead of JUL
    SLF4JBridgeHandler.removeHandlersForRootLogger();
    SLF4JBridgeHandler.install();
  }
}

, а затем мои тесты продлили JerseyTestSFL4J.

0 голосов
/ 05 мая 2017

В моем приложении регистрация на Джерси (с правильными pom.xml и logback.xml) работает нормально только с

    SLF4JBridgeHandler.install(); 

Для тестов вы можете сделать базовый абстрактный тест с общей конфигурацией и расширить из него другие JUnit:

public abstract class AbstractTest {

    private static final Logger LOG = LoggerFactory.getLogger(AbstractTest.class);

    static {
        SLF4JBridgeHandler.install();
    }

    @Rule
    public ExpectedException thrown = ExpectedException.none();

    @Rule
    // http://stackoverflow.com/questions/14892125/what-is-the-best-practice-to-determine-the-execution-time-of-the-bussiness-relev
    public Stopwatch stopwatch = new Stopwatch() {
        @Override
        protected void finished(long nanos, Description description) {
           ...
0 голосов
/ 22 ноября 2010

Как это звучит, если вы хотите, чтобы дескриптор конфигурации JUL / SLF4J был до того, как JUnit начнет тестирование, чтобы его можно было использовать для всех тестов? Вот способ, которым вы могли бы сделать это.

выход

MySuite.init()
MySuite()
getSuiteTests()
MyTest.init()
MyTest()
test()

код

@RunWith(AbstractTestSuite.TestSuiteRunner.class)
public abstract class AbstractTestSuite {
   public static class TestSuiteRunner extends Suite {
      public TestSuiteRunner(Class<?> klass) throws Exception {
         super(klass, ((Class<? extends AbstractTestSuite>) klass).newInstance().getSuiteClasses());
      }
   }

   public Class<?>[] getSuiteClasses() {
      List<Class<?>> all = new ArrayList<Class<?>>();
      for (Class<?> testClass : getSuiteTests()) {
         all.add(testClass);
      }
      return all.toArray(new Class<?>[0]);
   }

   protected abstract Iterable<Class<?>> getSuiteTests();
}

public class MySuite extends AbstractTestSuite {
   public static class MyTest {
      static {
         System.out.println("MyTest.init()");
      }

      public MyTest() {
         System.out.println("MyTest()");
      }

      @Test
      public void test() {
         System.out.println("test()");
         assertTrue(true);
      }
   }

   static {
      System.out.println("MySuite.init()");
   }

   public MySuite() {
      System.out.println("MySuite()");
   }

   @Override
   protected Iterable<Class<?>> getSuiteTests() {
      System.out.println("getSuiteTests()");
      return Arrays.asList(new Class<?>[] {MyTest.class});
   }
}
...