Java的ClassPath问题

在文章《Spark Submit的ClassPath问题》中,我探讨了针对spark-submit的Jar包,如何指定外部依赖的Jar包。同样的问题在本地部署时仍然存在。此时,运行Jar并不是通过spark-submit,而是通过java命令,例如:

exec java -Xmx2000m -DMORT_HOME=$MORT_HOME -Ddata-set-parquet.path=$MORT_HOME/parquet -Dconfig.file=$MORT_HOME/mort.conf -jar $MORT_HOME/target/mort.jar > $MORT_HOME/mort_console.log 2>&1

这里-jar参数后面指定的就是我们要运行Jar包,而在该Jar包中Java类,回去调用一个第三方的jar包,且jar包并没有被放到mort.jar包中。

通过查看java命令的帮助文档,我最初以为通过设置-classpath参数来指定外部依赖包就可以轻松解决。然而事情的发展并非我所愿,运行时仍然报告找不到第三方Jar包中相关类的错误。查阅文档,发现:

当使用-jar参数运行的时候,java VM会屏蔽所有的外部classpath,而只以本身yourJar.jar的内部class作为类的寻找范围。

一个解决方案是使用-Xbootclasspath参数,注意需要添加/a,从而保证该参数设置的classpath放在核心class搜索路径后。则前面的命令被修改为:

exec java -Xmx2000m -DMORT_HOME=$MORT_HOME -Ddata-set-parquet.path=$MORT_HOME/parquet -Dconfig.file=$MORT_HOME/mort.conf -Xbootclasspath/a:$MORT_HOME/thirdparty_jars/customer_provided.jar: -jar $MORT_HOME/target/mort.jar > $MORT_HOME/mort_console.log 2>&1

注意,若有多个classpath需要设置,在Unix/Linux/Mac下,分隔符为“:”,在windows下则使用“;”作为分隔符。

资料还提到可以将要依赖的第三方jar包放在JVM的扩展class路径下,即{java_home}\jre\lib\ext目录下。一旦设置正确,就无需修改任何配置文件了。

2017-06-26 14:35104java