明明配置了CLASSPATH,但是依然提示java.lang.ClassNotFoundException错误的一种可能

背景

有一个C++项目会调用Hadoop,该项目在部署时会利用脚本来配置所需要的CLASSPATH和其他环境变量。
在启动时发现报如下错误:

Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/hadoop/conf/Configuration
Caused by: java.lang.ClassNotFoundException: org.apache.hadoop.conf.Configuration
	at java.net.URLClassLoader$1.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(Unknown Source)
	at java.lang.ClassLoader.loadClass(Unknown Source)
	at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)

显而易见,是类的包找不到,通常状况就是CLASSPATH配置错误,或者真的缺失该包。

问题排查

首先排除了classpath不存在,和包不在的情况。通过export命令,查看环境变量,发现打印出的classpath也没有问题。
最后用gdb单步调试,去看到底哪里出了问题,调试时发现打印的CLASSPATH路径如下:

$3 = 0x4aa6000 "/thirdparty/hadoop/hadoop-2-core.jar:\033[0m\033[0m/thirdparty/hadoop/lib/abaci-core-3.29.0.jar\033[0m:\033[0m/thirdparty/hadoop/lib/ant-1.8.1.jar\033[0m:\033[0m/thirdparty/hadoop/"...

可以看到里面有\033[0m\033[0m 这种奇怪的字符,猜测就是它导致了classpath不正确的问题。
单这个特殊字符串是什么意思呢?通过Google发现,是linux中为了让shell输出的字体带颜色的设置。
那为何会引入这些控制字符呢?我们发现是因为该classpath是由一个脚本设置的,如下:

for f in `ls ${HADOOP_HOME}/lib/*.jar`; do
    CLASSPATH=${CLASSPATH}:$f
done
export CLASSPATH

脚本中会用到ls逐个取每个包的名字,而查看~/.bashrc的设置,正好有一个

alias ls='ls --color'

于是真相大白,就是这个参数引入了颜色控制字符。而颜色配置信息,在shell中进行export时正好看不到,这就是为何export时看到的路径是正确的,但是程序通过

 getenv("CLASSPATH");

获取到的环境变量就不正确的原因。

问题解决

去掉bashrc中的ls特殊配置即可。
对于线上部署的要控制好环境变量,不要修改常用的shell命令,当在别人的机器上部署出现类似问题时,不妨看一下是不是这种问题导致的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值