2010-11-08 12 views
19

He encontrado a useful article que explica cómo hacer que Jersey use SLF4J en lugar de JUL. Ahora mi unidad de prueba se parece (y funciona perfectamente):¿Cómo hacer que Jersey use SLF4J en lugar de 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 { 
    // ... 
    } 
} 

Mi pom.xml incluye las siguientes dependencias:

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

Funciona perfectamente, pero no quiero hacer la misma configuración en todos prueba de unidad. Es una duplicación de código obvia, que me gustaría evitar. ¿Cómo puedo hacer esto de manera más efectiva?

ps. Tal vez no es posible optimizar el código anterior y estoy haciendo lo mejor que puedo?

+0

Simplemente una mejora para usted initLogger(), puede usar esto: SLF4JBridgeHandler.removeHandlersForRootLogger(); java.util.logging.LogManager.getLogManager(). Reset(); SLF4JBridgeHandler.install(); – amgohan

Respuesta

5

La mejor manera de hacerlo es a través de una costumbre Listener. Al inicializarse antes del servlet JSF, debe configurar el puente jul-to-slf4j en contextInitialized(ServletContextEvent).

+3

Solo para tu información, el puente jul-to-slf4j puede ser costoso para el rendimiento. http://www.slf4j.org/legacy.html#jul-to-slf4j – onejigtwojig

+0

Estas personas http://projects.lidalia.org.uk/sysout-over-slf4j/quickstart.html proporcionan un contenedor que redirigirá su stdout y stderr a sl4j utilizando su jar, agregando un listener de clase a su web.xml y agregando otra línea de código. Lo intenté, pero no tuve suerte configurándolo correctamente. (No busqué más.) De todos modos, tal vez esto podría ser de ayuda para alguien. –

0

¿Qué le parece que desea que el controlador de configuración JUL/SLF4J antes JUnit comience a probar para que pueda ser cubierto para todas las pruebas? Aquí hay una manera en que podrías hacer eso.

salida

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

Código

@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 ¿Puedo hacer lo mismo ** sin ** código Java, solo con archivos de configuración 'XML/.properties'? – yegor256

13

Si está utilizando la API de cliente, podrá manualmente redirigir los registros para SLF4J (nótese que se puede romper en futuras versiones aunque parece poco probable):

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

En mi aplicación Jersey registro (con adecuada pom.xml y logback.xml) funciona bien únicamente con

SLF4JBridgeHandler.install(); 

Para las pruebas se pueden hacer de base abstracta prueba con configuración común y se extiende otra JUnit de ella:

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

Esto funcionó para mí:

public abstract class JerseyTestSFL4J extends JerseyTest { 

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

y luego tener mis pruebas se extienden JerseyTestSFL4J.

Cuestiones relacionadas