maven java.lang.NoClassDefFoundError with provided scope

关于maven中执行类遇到的java.lang.NoClassDefFoundError的问题

昨天有个同事问我,在Flink某个包中加了一个类用来进行测试,结果运行就会报如下错误

1
2
3
4
5
6
7
8
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/flink/api/common/serialization/DeserializationSchema
at com.didi.flink.app.FlinkTableSinkTest.main(FlinkTableSinkTest.scala)
Caused by: java.lang.ClassNotFoundException: org.apache.flink.api.common.serialization.DeserializationSchema
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 1 more

排查后怀疑是pom中该jar的依赖scope是provided导致的,测试删除后就解决了。

1
2
3
4
5
6
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-streaming-java_${scala.binary.version}</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>

但是觉得这样会很麻烦,所有其他用到的类都需要去除provided了?顺手Google了一下,Stack Overflow上有人问过同样的问题(这个人竟然是之前blink meetup上的flink+zeppelin的演讲者章剑锋(简锋)

https://stackoverflow.com/questions/30453269/maven-provided-dependency-will-cause-noclassdeffounderror-in-intellij

简单的说是因为provided的scope只在编译期和test期间有效,所以正确的姿势应该是测试类就放在测试包下面测试,这样provided的包依然是有效的

谢谢支持