После добавления в проект теста, потребовалась зависимость log4j-core, почему?

Я использую систему логирования org.slf4j.

Но когда создал первый JUnit тест с использованием библиотек

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.1.9.RELEASE</version>
            <scope>test</scope>
        </dependency>

Сообщение выводится следующее:

ERROR StatusLogger Log4j2 could not find a logging implementation. Please add log4j-core to the classpath. Using SimpleLogger to log to the console...

Сам тест выглядит так:

import net.os.goodcourses.configuration.*;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.forwardedUrl;

@RunWith(SpringRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes = {ElasticSearchConfig.class, EmailConfig.class, JPAConfig.class, MVCConfig.class, ResumeWebApplicationInitializer.class, SecurityConfig.class, ServiceConfig.class})
public class CourseControllerTest {

    @Autowired
    private WebApplicationContext context;

    private MockMvc mockMvc;

    @Before
    public void setup() {
        mockMvc = MockMvcBuilders
                .webAppContextSetup(context)
                .build();
    }

    @Test
    public void testMainPageCourses() throws Exception {
        this.mockMvc.perform(get("/courses"))
                .andExpect(forwardedUrl("/WEB-INF/JSP/courses.jsp"));
    }
}

Откуда могла взяться зависимость Log4j2?


Ответы (1 шт):

Автор решения: Oleg Marchenko

Так как Spring под капотом глубоко в недрах использует JCL (Java Common Logging) для логгирования, то необходимо правильно настроить эту часть системы.

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

Для того, чтобы подружить Spring и Slf4j необходимо исключить зависимость из spring-core на commons-logging библиотеку:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <exclusions>
        <exclusion>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>

И после этого добавить зависимость на некий мост, между JCL и Slf4j:

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>jcl-over-slf4j</artifactId>
</dependency>

Далее, так как Вы хотите использовать Log4j в качестве реализации Slf4j, необходимо указать его зависимости:

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j-impl</artifactId>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
</dependency>

Теперь можно с уверенностью сказать, что Вы используете не JCL для логгирования, а Slf4j с реализацией Log4j.

→ Ссылка