2010-11-08 7 views
19

Я нашел a useful article, в котором объясняется, как заставить Джерси использовать SLF4J вместо JUL. Теперь мой блок тест выглядит (и это работает отлично):Как заставить Джерси использовать 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 { 
    // ... 
    } 
} 

My 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> 

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

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

+0

Простое дополнение к вам initLogger(), вы можете использовать это: SLF4JBridgeHandler.removeHandlersForRootLogger(); java.util.logging.LogManager.getLogManager(). Reset(); SLF4JBridgeHandler.install(); – amgohan

ответ

5

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

+3

Просто FYI, мост jul-to-slf4j может быть дорогостоящим по производительности. http://www.slf4j.org/legacy.html#jul-to-slf4j – onejigtwojig

+0

Эти люди http://projects.lidalia.org.uk/sysout-over-slf4j/quickstart.html предоставляют банку, которая будет перенаправлять ваш stdout и stderr на sl4j, используя их банку, добавив слушателя класса к вашему web.xml и добавив еще одну строку кода. Я попробовал, но не повезло, правильно настроив его. (Не смотрел дальше.) В любом случае, может быть, это может помочь кому-то. –

0

Что вы думаете о том, что вы хотите обработать конфигурацию 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}); 
    } 
} 
+0

@TJ Могу ли я сделать то же ** без ** Java-кода, только с конфигурационными файлами 'XML/.properties'? – yegor256

13

Если вы используете клиентский 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); } 
} 
0

В моем приложении Джерси каротажного (с надлежащей 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

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

public abstract class JerseyTestSFL4J extends JerseyTest { 

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

, а затем с моих тестов продлить JerseyTestSFL4J.

Смежные вопросы