spark-submit提交Java WordCount报ClassNotFoundException异常及根因疑惑
显式指定
--class仍触发ClassNotFoundException的根因 核心问题本质
你之前显式传参失败、配完pom主类后不传参就能正常运行,根本不是spark-submit的加载逻辑问题,是提交命令里的类名夹带了人眼不可见的特殊字符:
- 从你的提交命令、报错日志里的类名字符串可以看到,
JavaWordCount前面携带了零宽空格字符(Unicode编码U+200B),这类字符是从文档、网页、聊天窗口复制命令时经常被夹带的,没有宽度、没有视觉显示,肉眼完全察觉不到 - spark-submit做类加载时,是严格按照你传入的字符串做类名匹配的,它实际识别到的待加载类名是「零宽空格 + JavaWordCount」,和Jar包内真实存在的
JavaWordCount类名完全不匹配,因此抛出ClassNotFoundException - 你在pom里配置完
<mainClass>后,spark-submit在没检测到显式--class参数时,会直接读取Jar包内MANIFEST.MF文件里记录的主类信息做加载,这个信息是构建时写入的,不存在外部复制夹带的特殊字符,所以能正常加载到目标类,也就解决了问题。
为什么之前的排查动作没定位到问题
你之前做的三步校验逻辑都是对的,但都没有覆盖到「传入参数带不可见字符」的场景:
- 用
javap校验类结构时,类名是你手动输入的,不带特殊字符,自然能正常匹配Jar包内的类 - 直接查看Jar包内部结构、MANIFEST配置时,检查的都是Jar包内本身的内容,没有和你提交命令里传的参数字符串做逐字符对比
- 从视觉上看报错日志里的类名,和真实类名完全一模一样,根本不会想到中间藏了个不可见字符
实操验证方法
- 把你之前触发报错的那串
--class后面的类名完整复制出来,粘贴到本地文本编辑器里,把光标移动到类名的最开头按向右键,会发现光标需要按两次才能跳过第一个字符,证明类名前面夹带了一个不可见字符 - 重新逐字敲写一遍spark-submit命令,哪怕不配置pom里的主类,显式传
--class JavaWordCount也能正常提交运行,不会再报类找不到的错误
日常提交的避坑提示
- 涉及类全限定名、文件路径的参数,尽量手动逐字输入,不要直接跨文档复制长段命令,避免夹带不可见特殊字符
- 遇到类名看起来完全正确但仍报
ClassNotFoundException的场景,优先检查传参字符串的字符长度,对比真实类名的长度找差异 - 把主类信息写入Jar包的MANIFEST配置,确实能减少很多提交时的人为输入错误
内容的提问来源于stack exchange,提问作者Eric Fang
相关产品推荐
相关产品推荐

