背景
相信大家看到這個文章對訊息服務器已經不陌生了,筆者也是在平日無聊想著自己撰寫一套關于RockerMQ 的訊息灰度框架的時候,準備本地搭建一個RockerMQ服務環境時遇到了一個頭疼的問題,在執行RockerMQ官網的Topic創建的時候(sh bin/mqadmin updatetopic -n localhost:9876 -t TestTopic),出現了報錯 /Library/Internet: No such file or directory,
報錯分析
在整個啟動rockermq的NameServer和Broker的時候都是很順利的,只是 bin/mqadmin updatetopic 執行命令報錯,
報錯內容:
[XX:rocketmq-5.0.0 baizhuangli$ sh bin/mqadmin updatetopic -n localhost:9876 -t TestTopic
/Users/xiaobai/Documents/mw/rocketmq-all-5.0.0-source-release/distribution/target/rocketmq-5.0.0/rocketmq-5.0.0/bin/tools.sh: line 56: /Library/Internet: No such file or directory
xiaobaizhuangli:rocketmq-5.0.0 baizhuangli$ pwd
我們針對性的對執行檔案進行分析: /bin/tools.sh: line 56: /Library/Internet: No such file or directory
打開報錯的執行檔案,在報錯行的前面增加一下輸出要執行的內容,

# 增加輸出目標錯誤行(56行執行的內容)
55 echo $JAVA ${JAVA_OPT} "$@"
56 $JAVA ${JAVA_OPT} "$@"
再次執行創建topic的陳述句,可以看到輸出的陳述句中其實是想要執行類
[xiaobai:rocketmq-5.0.0 baizhuangli$ sh bin/mqadmin updatetopic -n localhost:9876 -t TestTopic
/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java -server -Xms1g -Xmx1g -Xmn256m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=128m -cp .:/Users/xiaobai/Documents/mw/rocketmq-all-5.0.0-source-release/distribution/target/rocketmq-5.0.0/rocketmq-5.0.0/bin/../conf:/Users/xiaobai/Documents/mw/rocketmq-all-5.0.0-source-release/distribution/target/rocketmq-5.0.0/rocketmq-5.0.0/bin/../lib/*: org.apache.rocketmq.tools.command.MQAdminStartup updatetopic -n localhost:9876 -t TestTopic
/Users/xiaobai/Documents/mw/rocketmq-all-5.0.0-source-release/distribution/target/rocketmq-5.0.0/rocketmq-5.0.0/bin/tools.sh: line 56: /Library/Internet: No such file or directory
執行的目標陳述句如下,本質上我們可以直接拷貝出來進行執行,
/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java -server -Xms1g -Xmx1g -Xmn256m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=128m -cp .:/Users/xiaobai/Documents/mw/rocketmq-all-5.0.0-source-release/distribution/target/rocketmq-5.0.0/rocketmq-5.0.0/bin/../conf:/Users/xiaobai/Documents/mw/rocketmq-all-5.0.0-source-release/distribution/target/rocketmq-5.0.0/rocketmq-5.0.0/bin/../lib/*: org.apache.rocketmq.tools.command.MQAdminStartup updatetopic -n localhost:9876 -t TestTopic
當你拷貝陳述句直接執行之后,依舊會報錯,提示 -bash: /Library/Internet: No such file or directory;
好的,到此我們可以看到/Library/Internet 這個命令壓根就不是一個可執行的命令,是不是很奇怪,這個這個腳本中$JAVA=$JAVA_HOME怎么是 /Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java, 而不是我們自己下載安裝的JDK的路徑呢?我們本地查看一下JAVA_HOME的取值明明是 /Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home 才對呀,
是的,我們自己定義環境變數是在~/.bash_profile中,但是這個啟動腳本讀取的是系統里設定的,當我們java_home的lib存在兩個選項時,系統默認使用了第一個,也就是
/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home,所以導致我們命令執行失敗了,
通過 /usr/libexec/java_home -V 查看可選擇的lib和系統使用的選項,(這個地方地方目前沒有比較好的切換為自己版本的方式)
[xiaobai:Internet Plug-Ins baizhuangli$ /usr/libexec/java_home -V
Matching Java Virtual Machines (2):
1.8.121.13 (x86_64) "Oracle Corporation" - "Java" /Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home
1.8.0_121 (x86_64) "Oracle Corporation" - "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home
/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home
擴展一下 /Library/Internet Plug-Ins是Mac系統下 插件集合
[xiaobaizhuangli:Internet Plug-Ins baizhuangli$ cd /Library/Internet\ Plug-Ins
[xiaobaizhuangli:Internet Plug-Ins baizhuangli$ pwd
/Library/Internet Plug-Ins
[xiaobaizhuangli:Internet Plug-Ins baizhuangli$ ls
DM_CCB_NetSignPlugin.plugin HDZB_CCB_SignPlugin.plugin TDR_CCB_NetSignPlugin.plugin flashplayer.xpt
Flash Player.plugin JavaAppletPlugin.plugin WD_CCB_NetSignPlugin.plugin
# 其中JavaAppletPlugin.plugin 下面都是JAVA的JDK
問題修復
上面我們既然已經找到了問題,那么我們只需要將腳本【rocketmq-5.0.0/bin/tools.sh】中獲取java_home的地方修改為我們自己下載安裝的JDK的lib目錄理論上就可以,這樣就不會因為/Library/Internet Plug-Ins/中間存在空格,導致可執行命令找到不到的問題了,我們對執行的執行的腳本做一些簡單修改,主要是export自己的jdk路徑到環境變數中,
# 上面省略了一下內容,
find_java_home
# 在JAVA_HOME獲取之前,通過export命令將自己的JDK的HOME設定到環境變數,從而對本次啟動生效
export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home
[ ! -e "$JAVA_HOME/bin/java" ] && JAVA_HOME=$HOME/jdk/java
[ ! -e "$JAVA_HOME/bin/java" ] && JAVA_HOME=/usr/java
[ ! -e "$JAVA_HOME/bin/java" ] && error_exit "Please set the JAVA_HOME variable in your environment, We need java(x64)!"
export JAVA_HOME
export JAVA="$JAVA_HOME/bin/java"
export BASE_DIR=$(dirname $0)/..
export CLASSPATH=.:${BASE_DIR}/conf:${BASE_DIR}/lib/*:${CLASSPATH}
#===========================================================================================
# JVM Configuration
#===========================================================================================
JAVA_OPT="${JAVA_OPT} -server -Xms1g -Xmx1g -Xmn256m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=128m"
JAVA_OPT="${JAVA_OPT} -cp ${CLASSPATH}"
$JAVA ${JAVA_OPT} "$@"
然后再次執行我們的陳述句,可以看到已經我們的修改已經生效,
[xiaobai:rocketmq-5.0.0 baizhuangli$ sh bin/mqadmin updatetopic -n localhost:9876 -t TestTopic
/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/bin/java -server -Xms1g -Xmx1g -Xmn256m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=128m -cp .:/Users/xiaobai/Documents/mw/rocketmq-all-5.0.0-source-release/distribution/target/rocketmq-5.0.0/rocketmq-5.0.0/bin/../conf:/Users/xiaobai/Documents/mw/rocketmq-all-5.0.0-source-release/distribution/target/rocketmq-5.0.0/rocketmq-5.0.0/bin/../lib/*: org.apache.rocketmq.tools.command.MQAdminStartup updatetopic -n localhost:9876 -t TestTopic
總結
對于我們JAVA開發同學來說,經常會自己下載指定版本的JDK包來運行我們的程式,通常撰寫代碼和運行的時候,我們可以在IEDA上選擇我們JDK版本及lib的路徑,或者使用的不是/Library/Internet Plug-Ins/ 這種帶有空格包下的目錄,幾乎不會出現這種問題,
但是使用原始碼啟動一些工具或者開源專案時,開源專案的shell腳本中不會完全考慮到我們每個開發者的本地環境,就會莫名其妙的報一些錯誤,這次是對于Rocket MQ的除錯出現的這個問題,當然對于其他的專案(例如 Nacos )也發現過這種問題,
所以我們要在出現錯誤時,仔細的分析報錯內容和報錯來源,進入報錯產生的地方,通過輸出列印、設定預期值等方式來進行除錯和錯誤排查,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/518950.html
標籤:其他
上一篇:PHP記憶體木馬病毒實作原理剖析
下一篇:C++基礎
