简体   繁体   English

为什么以 jar 运行时会出现 java.lang.ClassNotFoundException,但与 IntelliJ IDEA 配合良好

[英]Why get java.lang.ClassNotFoundException when run as jar, but work well with IntelliJ IDEA

spring boot version: 2.4.1 spring 引导版本:2.4.1

spring cloud version: 2020.0.0 spring 云端版本:2020.0.0

My code我的代码

@Configuration
public class BaseConfig {

    @Bean
    public Module sortJacksonModule() {
        return new SortJacksonModule();
    }
}

my pom.xml dependency我的 pom.xml 依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-commons</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-openfeign-core</artifactId>
</dependency>

my pom.xml plugin我的 pom.xml 插件

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

When run with IntelliJ IDEA, it work well.使用 IntelliJ IDEA 运行时,它运行良好。

But when run with jar(by mvn clean package ), it show但是当用 jar 运行时(通过mvn clean package ),它显示

Caused by: java.lang.NoClassDefFoundError: feign/codec/EncodeException
        at org.springframework.cloud.openfeign.support.SortJacksonModule.setupModule(SortJacksonModule.java:47) ~[spring-cloud-openfeign-core-3.0.0.jar!/:3.0.0]
        at com.fasterxml.jackson.databind.ObjectMapper.registerModule(ObjectMapper.java:819) ~[jackson-databind-2.11.3.jar!/:2.11.3]
        at com.fasterxml.jackson.databind.ObjectMapper.registerModules(ObjectMapper.java:1021) ~[jackson-databind-2.11.3.jar!/:2.11.3]
        at org.springframework.http.converter.json.Jackson2ObjectMapperBuilder.configure(Jackson2ObjectMapperBuilder.java:712) ~[spring-web-5.3.2.jar!/:5.3.2]
        at org.springframework.http.converter.json.Jackson2ObjectMapperBuilder.build(Jackson2ObjectMapperBuilder.java:680) ~[spring-web-5.3.2.jar!/:5.3.2]
        at org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$JacksonObjectMapperConfiguration.jacksonObjectMapper(JacksonAutoConfiguration.java:101) ~[spring-boot-autoconfigure-2.4.1.jar!/:2.4.1]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_232]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_232]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_232]
        at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_232]
        at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.3.2.jar!/:5.3.2]
        ... 113 common frames omitted
Caused by: java.lang.ClassNotFoundException: feign.codec.EncodeException
        at java.net.URLClassLoader.findClass(URLClassLoader.java:382) ~[na:1.8.0_232]
        at java.lang.ClassLoader.loadClass(ClassLoader.java:418) ~[na:1.8.0_232]
        at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:151) ~[demo-spring-core-11-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
        at java.lang.ClassLoader.loadClass(ClassLoader.java:351) ~[na:1.8.0_232]
        ... 124 common frames omitted

After study the error log, I found that feign.codec.EncodeException is optional dependency in spring-cloud-openfeign-core , so ClassNotFoundException is right behavior(optional dependency not include in final jar).研究错误日志后,我发现feign.codec.EncodeExceptionspring-cloud-openfeign-core中的可选依赖,所以 ClassNotFoundException 是正确的行为(可选依赖不包含在最终 jar 中)。

So my question is: Why IntelliJ IDEA can run without any error?所以我的问题是:为什么IntelliJ IDEA可以无错运行? I try both IntelliJ IDEA run and mvn spring-boot:run, both work fine.我尝试了 IntelliJ IDEA run 和 mvn spring-boot:run,两者都运行良好。

update: add example更新:添加示例

After more study, I found out this only happen when the class not called.经过更多的研究,我发现只有当 class 没有被调用时才会发生这种情况。

        try {
            System.out.println("not important code");
        } catch (Exception e) {
            throw new EncodeException("not exist class");
        }

In this example, the try catch never throw an exception.在这个例子中,try catch 永远不会抛出异常。 And the EncodeException class is in an optional dependency.并且EncodeException class 处于可选依赖项中。 This code run well in IntelliJ IDEA, but fail when run as java -jar xxx.jar此代码在 IntelliJ IDEA 中运行良好,但在以java -jar xxx.jar运行时失败

========== update again with minimal demo ========== 用最少的演示再次更新

I create a minimal demo to reproduce this issue.我创建了一个最小演示来重现此问题。

  • a standalone demo-module一个独立的演示模块
        <dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-core</artifactId>
            <version>10.10.1</version>
            <optional>true</optional>
        </dependency>
import feign.codec.EncodeException;

/**
 * Hello world!
 */
public class App {

    public void testOptional() {
        try {
            System.out.println("test");
        } catch (Exception e) {
            throw new EncodeException("never throw this");
        }
    }
}
  • demo spring project(create by spring initializr and add a dependency)演示 spring 项目(通过spring initializr创建并添加依赖项)
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>demo-module</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
@Component
public class MyMain implements ApplicationRunner {

    @Override
    public void run(ApplicationArguments args) throws Exception {
        new App().testOptional();
    }
}

Inspect your project classpath in Idea ( CTRL-Alt-Shift-S ) - I daresay optional jar is somewhere on module compile classpath and it is enough to run your class in IDE - but not in standalone jar. Optional means in maven context that it is present on classpath while compiling, but not packed into resulting artifact.在 Idea ( CTRL-Alt-Shift-S ) 中检查你的项目类路径——我敢说可选的 jar 在模块编译类路径上的某个地方,它足以在 IDE 中运行你的 class——但不是在独立的 jar 中。可选意味着在 maven 上下文中它编译时出现在类路径中,但未打包到生成的工件中。

There is an option called Enable launch optimization in IntelliJ IDEA run config, uncheck it and everything work as expected.在 IntelliJ IDEA run config 中有一个名为Enable launch optimization的选项,取消选中它,一切都会按预期进行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在 IntelliJ IDEA 中运行时出现 java.lang.ClassNotFoundException - java.lang.ClassNotFoundException when running in IntelliJ IDEA intelliJ IDEA:java.lang.ClassNotFoundException - intelliJ IDEA: java.lang.ClassNotFoundException 从IntelliJ IDEA运行Mule拼写时出现java.lang.ClassNotFoundException - java.lang.ClassNotFoundException when run Mule apllication from IntelliJ IDEA 尝试在 intellij-idea 中使用 JAR 文件进行编译,出现错误 java.lang.NoClassDefFoundError 和 java.lang.ClassNotFoundException - Trying to compile using JAR file in intellij-idea getting ERRORS java.lang.NoClassDefFoundError and java.lang.ClassNotFoundException java.lang.RuntimeException:尝试在Elastic MapReduce上运行Jar作业时出现java.lang.ClassNotFoundException - java.lang.RuntimeException: java.lang.ClassNotFoundException when trying to run Jar job on Elastic MapReduce 运行java -jar时的java.lang.ClassNotFoundException - java.lang.ClassNotFoundException when running java -jar Gradle:java.lang.ClassNotFoundException:运行优步时 Jar - Gradle : java.lang.ClassNotFoundException : When running Uber Jar 从jar文件加载类时出现java.lang.ClassNotFoundException - java.lang.ClassNotFoundException when loading a class from a jar file 带jar文件的Crontab java.lang.ClassNotFoundException - Crontab java.lang.ClassNotFoundException with a jar file intellij IDEA调试模式:线程“main”中的异常java.lang.ClassNotFoundException:kotlinx.coroutines.debug.AgentPremain - intellij IDEA debug mode: Exception in thread "main" java.lang.ClassNotFoundException: kotlinx.coroutines.debug.AgentPremain
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM