Jar包問題查找腳本

目錄

一、查找jar包類名關鍵字

二、在jar包中查找指定字段

三、檢查jar包衝突腳本


一、查找jar包類名關鍵字

腳本功能

此腳本在Jar包中的包名和類名中查找某一關鍵字,並高亮顯示匹配的Jar包名稱和路徑,

解決問題

多用於定位java.lang.NoClassDefFoundErrorjava.lang.ClassNotFoundException的問題,以及類版本重複或者衝突的問題等。

腳本代碼

#!/bin/bash
### 查找jar包中的字段,多用於定位java.lang.NoClassDefFoundError和java.lang.ClassNotFoundException的問題,以及類版本重複或者衝突的問題等。
find . -name "*.jar" > /tmp/find_in_jar_temp
while read line
do
  if unzip -l $line | grep $1 &> /tmp/find_in_jar_temp_second
  then
    echo $line | sed 's#\(.*\)#\x1b[1;31m\1\x1b[00m#'
    cat /tmp/find_in_jar_temp_second
  fi
done < /tmp/find_in_jar_temp

命令格式

find-jar-field 關鍵字或者類名 路徑
例如
./find-jar-field TaskQueue ./lib/

命令效果

二、在jar包中查找指定字段

腳本功能

這個腳本在Jar包中進行二進制內容查找指定的字段

解決問題

經常可以解決一些很神奇的問題,例如某些功能上線沒有生效、某些日誌沒有打印,上了新功能卻沒有展示,就可以通過這個命令查找打的包是否有問題。

腳本代碼

#!/bin/bash
### 查找路徑下jar包包含的字段

if [ $# -lt 2 ];then
    echo 'Usage : jargrep text path'
    exit 1;
fi

LOOK_FOR=$1
LOOK_FOR=`echo ${LOOK_FOR//\./\/}`
folder=$2
echo "find '$LOOK_FOR' in $folder "
for i in `find $2 -name "*jar"`
do
    unzip -p $i | grep "$LOOK_FOR" > /dev/null
    if [ $? = 0   ]
    then
        echo "==> Found \"$LOOK_FOR\" in $i"
    fi
done

命令格式

grep-jar  關鍵字或者類名 路徑
例如
./grep-jar TaskQue ./lib

命令效果

三、檢查jar包衝突腳本

腳本功能

此腳本用於識別衝突的Jar包,可以在一個根目錄下找到所有包含相同類的Jar包,並且根據相同類的多少來判斷Jar包的相似度。

解決問題

常常用於某些功能上線不可用或者沒有按照預期起到作用,使用此腳本分析是否存在兩個版本的類,而老版本的類被Java虛擬機加載,其實,JVM規範並沒有規定類路徑下相同類的加載順序,實現JVM規範的虛擬機的實現機制也各不相同,因此無法判斷相同的類中哪個版本的類會被先加載,因此Jar包衝突是個非常討厭的問題。

腳本代碼

#!/bin/bash
### 腳本用於識別衝突的Jar包,可以在一個根目錄下找到所有包含相同類的Jar包
if [ $# -eq 0 ];then
    echo "please enter classpath dir"
    exit -1
fi

if [ ! -d "$1" ]; then
    echo "not a directory"
    exit -2
fi

tmpfile="/tmp/.cp$(date +%s)"
tmphash="/tmp/.hash$(date +%s)"
verbose="/tmp/cp-verbose.log"

declare -a files=(`find "$1" -name "*.jar"`)
for ((i=0; i < ${#files[@]}; i++)); do
    jarName=`basename ${files[$i]}`
    list=`unzip -l ${files[$i]} | awk -v fn=$jarName '/\.class$/{print $NF,fn}'`
    size=`echo "$list" | wc -l`
    echo $jarName $size >> $tmphash
    echo "$list"
done | sort | awk 'NF{
    a[$1]++;m[$1]=m[$1]","$2}END{for(i in a) if(a[i] > 1) print i,substr(m[i],2)
}' > $tmpfile

awk '{print $2}' $tmpfile |
awk -F',' '{i=1;for(;i<=NF;i++) for(j=i+1;j<=NF;j++) print $i,$j}' |
sort | uniq -c | sort -nrk1 | while read line; do
    dup=${line%% *}
    jars=${line#* }
    jar1=${jars% *}
    jar2=${jars#* }
    len_jar1=`grep -F "$jar1" $tmphash | grep ^"$jar1" | awk '{print $2}'`
    len_jar2=`grep -F "$jar2" $tmphash | grep ^"$jar2" | awk '{print $2}'`
    # Modified by Robert 2017.4.9
    #len=$(($len_jar1 > $len_jar2 ? $len_jar1 : $len_jar2))
    len_jar1=`echo $len_jar1 | awk -F' ' '{print $1}'`
    len_jar2=`echo $len_jar2 | awk -F' ' '{print $1}'`
    if [ $len_jar1 -gt $len_jar2 ]
    then
      len=$len_jar1
    else
      len=$len_jar2
    fi
    per=$(echo "scale=2; $dup/$len" | bc -l)
    echo ${per/./} $dup $jar1 $jar2
done | sort -nr -k1 -k2 |
awk 'NR==1{print "Similarity DuplicateClasses File1 File2"}{print "%"$0}'| column -t

sort $tmpfile | awk '{print $1,"\n\t\t",$2}' > $verbose
echo "See $verbose for more details."

rm -f $tmpfile
rm -f $tmphash

命令格式

./jar-conflict-detect  關鍵字或者類名 路徑
例如
./jar-conflict-detect ./

命令效果

本文腳本已上傳CSDN,需要的可以自己去下載哈~地址爲:https://download.csdn.net/download/b379685397/12182444

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章