2010-11-08 37 views
19

Tôi đã tìm thấy a useful article giải thích cách làm cho Jersey sử dụng SLF4J thay vì JUL. Bây giờ kiểm tra đơn vị của tôi trông như thế (và nó hoạt động hoàn hảo):Làm sao để Jersey sử dụng SLF4J thay vì 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 của tôi bao gồm những phụ thuộc:

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

Nó hoạt động hoàn hảo, nhưng tôi không muốn làm cho cấu hình tương tự trong mỗi kiểm tra đơn vị. Đó là một bản sao mã rõ ràng, mà tôi muốn tránh. Làm thế nào tôi có thể làm điều này hiệu quả hơn?

ps. Có lẽ không thể tối ưu hóa mã ở trên và tôi đang làm hết sức mình có thể?

+0

Chỉ cần tăng cường cho bạn initLogger(), bạn có thể sử dụng điều này: SLF4JBridgeHandler.removeHandlersForRootLogger(); java.util.logging.LogManager.getLogManager(). Reset(); SLF4JBridgeHandler.install(); – amgohan

Trả lời

5

Cách tốt nhất để làm điều đó là thông qua một tùy chỉnh Listener. Được khởi tạo trước khi servlet JSF cần cấu hình cầu jul-to-slf4j trong contextInitialized(ServletContextEvent).

+3

Chỉ cần FYI, cầu jul-to-slf4j có thể tốn kém về hiệu suất. http://www.slf4j.org/legacy.html#jul-to-slf4j – onejigtwojig

+0

Những người này http://projects.lidalia.org.uk/sysout-over-slf4j/quickstart.html cung cấp một bình sẽ chuyển hướng stdout và stderr của bạn để sl4j bằng cách sử dụng jar của họ, thêm một người nghe lớp vào web.xml của bạn và thêm một dòng mã khác. Tôi đã thử nó, nhưng không có may mắn cấu hình nó đúng cách. (Không nhìn sâu hơn vào nó.) Dù sao, có lẽ điều này có thể giúp đỡ cho ai đó. –

0

Có vẻ như bạn muốn xử lý cấu hình JUL/SLF4J trước khi JUnit bắt đầu thử nghiệm để nó có thể được bao trả cho tất cả các thử nghiệm? Đây là cách bạn có thể làm điều đó.

Output

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 Tôi có thể thực hiện cùng một mã ** mà không có ** mã Java không, chỉ với các tệp cấu hình 'XML/.properties'? – yegor256

13

Nếu bạn đang sử dụng API khách hàng mà bạn có thể tự chuyển hướng các bản ghi để SLF4J (lưu ý rằng nó có thể phá vỡ trong các phiên bản tương lai mặc dù nó có vẻ như không):

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

Trong ứng dụng của tôi Jersey đăng nhập (với đúng pom.xmllogback.xml) hoạt động tốt chỉ với

SLF4JBridgeHandler.install(); 

Đối với các bài kiểm tra bạn có thể làm cơ sở trừu tượng thử nghiệm với cấu hình phổ biến và mở rộng JUnit khác từ nó:

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

này đã làm việc cho tôi:

public abstract class JerseyTestSFL4J extends JerseyTest { 

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

và sau đó có các bài kiểm tra của tôi kéo dài JerseyTestSFL4J.

Các vấn đề liên quan