Spring 引导非致命错误 ClassNotFoundException

Spring boot non-fatal errors ClassNotFoundException

我正在尝试创建 Spring 引导应用程序以与 Apache ActiveMQ 协作。

在启动期间我收到以下 "non-fatal" 错误:

java.lang.ClassNotFoundException: org.springframework.data.web.config.EnableSpringDataWebSupport
    at java.net.URLClassLoader.run(Unknown Source) ~[na:1.8.0_25]
    at java.net.URLClassLoader.run(Unknown Source) ~[na:1.8.0_25]
    at java.security.AccessController.doPrivileged(Native Method) ~[na:1.8.0_25]
    at java.net.URLClassLoader.findClass(Unknown Source) ~[na:1.8.0_25]
    at java.lang.ClassLoader.loadClass(Unknown Source) ~[na:1.8.0_25]
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) ~[na:1.8.0_25]
    at java.lang.ClassLoader.loadClass(Unknown Source) ~[na:1.8.0_25]

java.lang.ClassNotFoundException: org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
    at java.net.URLClassLoader.run(Unknown Source) ~[na:1.8.0_25]
    at java.net.URLClassLoader.run(Unknown Source) ~[na:1.8.0_25]
    at java.security.AccessController.doPrivileged(Native Method) ~[na:1.8.0_25]
    at java.net.URLClassLoader.findClass(Unknown Source) ~[na:1.8.0_25]
    at java.lang.ClassLoader.loadClass(Unknown Source) ~[na:1.8.0_25]
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) ~[na:1.8.0_25]
    at java.lang.ClassLoader.loadClass(Unknown Source) ~[na:1.8.0_25]

这是我的文件:

@Configuration
@EnableJms
public class ActiveMQTestConfig {

    @Bean
    // Strictly speaking this bean is not necessary as boot creates a default
    JmsListenerContainerFactory<?> myJmsContainerFactory(ConnectionFactory connectionFactory) {
        SimpleJmsListenerContainerFactory factory = new SimpleJmsListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        return factory;
    }

}

@Configuration
@ComponentScan("com.example.messages")
@SpringBootApplication
public class TestConfig {    
}

@Component
public class Receiver {

    /**
     * Get a copy of the application context
     */
    @Autowired
    ConfigurableApplicationContext context;

    /**
     * When you receive a message, print it out, then shut down the application.
     * Finally, clean up any ActiveMQ server stuff.
     */
    @JmsListener(destination = "mailbox-destination", containerFactory = "myJmsContainerFactory")
    public void receiveMessage(String message) {
        System.out.println("Received <" + message + ">");
        context.close();
        FileSystemUtils.deleteRecursively(new File("activemq-data"));
    }

}

@SpringApplicationConfiguration(classes = { TestConfig.class, ActiveMQTestConfig.class })
@RunWith(SpringJUnit4ClassRunner.class)
public class ReceiverTest {

    @Autowired
    private JmsTemplate jmsTemplate;

    @Test
    public void testReceiver() {
        // Clean out any ActiveMQ data from a previous run
        FileSystemUtils.deleteRecursively(new File("activemq-data"));

        // Send a message
        MessageCreator messageCreator = new MessageCreator() {
            @Override
            public Message createMessage(Session session) throws JMSException {
                return session.createTextMessage("ping!");
            }
        };

        System.out.println("Sending a new message.");
        jmsTemplate.send("mailbox-destination", messageCreator);

    }

}

日志配置 - logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <Pattern>
                %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
            </Pattern>
        </layout>
    </appender>

    <logger name="org.springframework" level="debug" additivity="false">
        <appender-ref ref="STDOUT" />
    </logger>

    <root level="error">
        <appender-ref ref="STDOUT" />
    </root>

</configuration>

来自parent-pom的依赖配置:

<!-- jUnit -->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>${junit.version}</version>
    <scope>test</scope>
</dependency>

<!-- Aspectj -->
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjrt</artifactId>
    <version>${aspectj.version}</version>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>${aspectj.version}</version>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjtools</artifactId>
    <version>${aspectj.version}</version>
</dependency>

<!-- Spring -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>${spring.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-beans</artifactId>
    <version>${spring.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>${spring.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>${spring.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-expression</artifactId>
    <version>${spring.version}</version>
</dependency>

<!-- Spring boot -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot</artifactId>
    <version>${spring.boot.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-autoconfigure</artifactId>
    <version>${spring.boot.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-logging</artifactId>
    <version>${spring.boot.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <version>${spring.boot.version}</version>
    <scope>test</scope>
</dependency>

<dependency>
    <groupId>javax.enterprise</groupId>
    <artifactId>cdi-api</artifactId>
    <version>${cdi-api.version}</version>
</dependency>

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>${commons-lang3.version}</version>
</dependency>
<dependency>
    <groupId>commons-validator</groupId>
    <artifactId>commons-validator</artifactId>
    <version>${commons-validator.version}</version>
</dependency>
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>${commons-io.version}</version>
</dependency>

<!-- Logging -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>${slf4j.version}</version>
</dependency>
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>${logback.version}</version>
</dependency>

此项目的依赖配置:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jms</artifactId>
    <version>${spring.version}</version>
</dependency>
<dependency>
    <groupId>org.apache.activemq</groupId>
    <artifactId>activemq-broker</artifactId>
    <version>${activemq.version}</version>
</dependency>

如何防止Spring Boot寻找未使用的类和注解?我在这个项目中不需要任何与网络相关的东西。

包括以下依赖项

       <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-commons</artifactId>
            <version>1.10.0.RELEASE</version>
        </dependency>

Spring 引导自动配置通过功能检测工作,很像普通 Spring 在某些地方所做的(比如在 Hibernate 版本之间动态切换)。

功能检测的工作原理是检查框架、库或 JDK 中一些众所周知的 classes/methods/annotations 是否可用。如果不是,则该功能不可用。

Spring 启动也不例外,它只是检查 class 是否可用。在您的情况下,它用于 Spring Data REST 和 Spring Security。对于调试 Spring Boot 记录那些在 DEBUG 时未检测到的功能。这是为了排除故障,如果某些东西不起作用,您可以看到您缺少库的哪一部分。

要禁用日志记录,只需不要在 DEBUG 记录所有内容。

有说明:https://github.com/spring-projects/spring-boot/issues/4121 "Spring Framework uses ASM to look at the bytecode. In this case it's found an annotation that isn't on the classpath. That means that metadata about the annotation will be unavailable, nothing more. When the class is actually loaded, the JVM drops the annotation as it's not on the class path."