[英]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.EncodeException
是spring-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.我创建了一个最小演示来重现此问题。
<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");
}
}
}
spring initializr
and add a dependency)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.