2010-05-19 6 views
1

여러분, 저는 방금 JSP/Servlet과 EJB 1.2를 기반으로 한 거대한 소스 트리를 가진이 회사에 가입했습니다. 설명서가 없습니다. 이 코드는 7 년 동안 문서화되지 않은 많은 변경 사항과 함께 작성되었습니다. 실행 추적에 도움이되는 도구가 있습니까? 중단 점을 두는 것이 나에게 많은 도움이되지 못한다.java tracing 스파게티 코드

+0

코드 변경 또는 재배치없이 메소드에 추적 기능을 제공하는 https://github.com/alfredxiao/jackplay를 시도 할 수 있습니다. –

답변

2

모든 사람의 의견을 보내 주셔서 감사합니다. 그것은 훌륭한 학습 경험이었습니다. html 보고서를 작성하는 쉘 스크립트를 작성했습니다. 여기에 전체 파일을 첨부합니다.

나는 일반 셸 프로그래머가 아니기 때문에이 작업을 몇 시간 동안하고 있었다. 따라서 코드 표준은 그리 좋지 않다. 그것은 인터넷에서 많은 커트/과거 일을 가지고 있습니다. 그것은 그러나 작동하며, sphegatti 코드를 통과하기 위해 취할 수있는 접근법을 제시합니다. 감사합니다 Amarsh

#!/usr/bin/bash 

# check the number of command line arguments 
clear 
echo "### CodeCrawler starting" 

# test input parameters 
if [[ $# < 2 ]]; then 
    echo "usage: % crawl inputFile/inputDir outputDir" 
    exit -1 
fi  

# the working directory is C:\CodeCrawler 
cd /cygdrive/c/CodeCrawler 

# find all files tha require analysis 
if [ -d $1 ]; then 
    find $1 | grep "\.java$" > allFiles$2 
    find $1 | grep "\.jsp$" >> allFiles$2 
    find $1 | grep "\.htm$" >> allFiles$2 
    find $1 | grep "\.html$" >> allFiles$2 
else if [ -f $1 ]; then 
    find $1 > allFiles$2 
    fi 
fi 

# get total no. of files to be scanned 
totalFiles=$(cat allFiles$2 | wc -l) 
scannedNoOfFiles=0; 
echo "### No of files to scan : $totalFiles" 

# create the index.html file 
rm -rf $2; mkdir $2;cd $2 
echo "<html><body bgcolor=\"#ccffff\"><h3>$1</h3>" > dir.html 

# crawl through the entire directory 
for rootFile in $(cat ../allFiles$2); do 

    scannedNoOfFiles=$((scannedNoOfFiles+1));echo;echo "### Scanning $scannedNoOfFiles/$totalFiles" 

    # create a dir for the output 
    rootFileDir=$(echo $rootFile | tr '/' '\n' | tail -1).dir 
    echo "### Storing output in $rootFileDir" 
    rm -rf $rootFileDir 
    mkdir $rootFileDir 
    cd $rootFileDir 

    # append to the index.html file 
    rootFileDirName=$(echo $rootFile | tr '/' '\n' | tail -1) 
    echo "<a href=\"$rootFileDir/index.html\" target=\"fileFrame\">$rootFileDirName</a><br>" >> ./../dir.html 

    # obtain all external jsp references 
    touch jsp.cwl 
    cat $rootFile | grep "\.jsp" | tr "'\"\?<>=,()[] " '\n' | sed 's/\.\.//g' | grep "\.jsp" | grep -v "http" | sort -u > tmp 
    for line in $(cat tmp);do 
     echo /$line | sed 's/\/\//\//g' >> jsp.cwl 
    done 

    # obtain all external js references 
    touch js.cwl 
    cat $rootFile | sed 's/\.jsp//g' | grep "\.js" | tr "'\"\?<>=,()[] " '\n' | sed 's/\.\.//g' | grep "\.js" | grep -v "http" | sort -u > tmp 
    for line in $(cat tmp);do 
     echo /$line | sed 's/\/\//\//g' >> js.cwl 
    done 

    # obtain all external css references 
    touch css.cwl 
    cat $rootFile | grep "\.css" | tr "'\"\?<>=,()[] " '\n' | sed 's/\.\.//g' | grep "\.css" | grep -v "http" | sort -u > tmp 
    for line in $(cat tmp);do 
     echo /$line | sed 's/\/\//\//g' >> css.cwl 
    done 

    # obtain all external htm references 
    touch htm.cwl 
    cat $rootFile | grep "\.htm" | tr "'\"\?<>=,()[] " '\n' | sed 's/\.\.//g' | grep "\.htm" | grep -v "http" | sort -u > tmp 
    for line in $(cat tmp);do 
     echo /$line | sed 's/\/\//\//g' >> htm.cwl 
    done 

    # obtain all database references 
    touch db.cwl 
    cat $rootFile | grep -i "select.*from" | sed 's/from/\nfrom/g' | sed 's/FROM/\nFROM/g' | grep -i "from" | sed 's/from//g'| sed 's/FROM//g' | awk '{print $1}' | tr '[;"]' ' ' | uniq > db.cwl 
    cat $rootFile | sed "s/.prepareStatement(\"/\nX_X_X/g" | grep "X_X_X" | sed "s/X_X_X//g" | tr '[ ,\$ ]' '\n' | head -1 | uniq >> db.cwl 

    # obtain all references to java classes. we include everything with signature com. and exclude "www" and "flight" 
    cat $rootFile | tr '["=%;/<>@\t) ]' '\n' | grep "com\." | grep -v "codepassion\." | grep -v "www" | grep -v "flight" | sort -u > tmp 
    echo > tmpDirectReferences 
    cat tmp | grep "(" >> tmpDirectReferences # directReferences are like au.com.mycompany.servlet.MiscServlet.getCckey() 
    echo > tmpDirectReferences 
    cat tmp | grep -v "(" >> tmpJavaFiles   # javaFiles are like Person aPerson; ... aPerson.getPolicy() 

    # read directReferences and produce the class.cwl file by identifying class and method 
    echo "#D# Looking for direct references" 
    while read classLine; do 
     methodName=$(echo $classLine | tr '\.' '\n' | tail -1 | sed 's/(//g') 
     className=$(echo $classLine | sed "s/\.$methodName(//g" | tr '[()]' ' ') 
     echo $methodName >> $className.cwl 
     echo "### class: $className method:$methodName" 
     echo $className >> tmpDirectReferencesReformed 
    done < tmpDirectReferences 

    # read javaFiles every fully qualified class name and grab the class from it. then grab the method from it 
    echo "#J# Looking for indirect references" 
    while read classLine; do 
     className=$(echo $classLine | tr '\.' '\n' | tail -1) 
     echo "#F# find: $classLine" 
     # indirect references are in the form className objectName ... and then objectName.methodName 
     cat $rootFile | grep "$className .*;" | sed -e "s/$className[ \t]\+\([a-zA-Z0-9_]\+\)[ \t]*[;=].*/\1/g" | sed 's/^[ \t]*//;s/[ \t]*$//' | sort -u > tmp$ClassName 
     # read tmp$className and find all properties and method references 
     while read methodLine; do 
     cat $rootFile | grep "$methodLine\." | tr '[ (]' '\n' | sed "s/$methodLine\./\n$methodLine\./g" | grep "$methodLine\." | sort -u | grep -v "[\"%]" | grep -v ".com." | tr '.' '\n' | grep -v "$methodLine" >> $classLine.cwl 
     done < tmp$ClassName 
     # direct references are className.methodName 
     cat $rootFile | grep "[()\"']$className\." | tr ' (' '\n' | grep "$className" | tr '.' '\n' | grep -v "$className" >> $classLine.cwl 
     cat $rootFile | grep "$className\." | tr ' (' '\n' | grep "$className" | tr '.' '\n' | grep -v "$className" >> $classLine.cwl 
    done < tmpJavaFiles 

    # consolidate all information to generate the html files 
    echo "### Generating index.html" 
    rootFileName=$(echo $rootFile | tr '/' '\n' | tail -1) 
    touch index.html 
    echo "<html><head><title>$rootFileName</title></head><body bgcolor=\"#ffffcc\">" >> index.html 
    echo "<h3>$rootFile</h3>" >> index.html 
    # put all java classes 
    echo "<br><h3>Referenced classes</h3>">> index.html 
    cat tmpDirectReferencesReformed | uniq >> tmpJavaFiles;cat tmpJavaFiles | uniq > tmpJavaFilesU; mv tmpJavaFilesU tmpJavaFiles 
    while read aLine; do 
     echo "- <a href=\"$aLine.html\" target=\"methodFrame\">$aLine</a><br>" >> index.html 
    done < tmpJavaFiles 
    # put all DBs 
    echo "<br><h3>Referenced Tables</h3>">> index.html 
    while read aLine; do 
     echo "- $aLine<br>" >> index.html 
    done < db.cwl 
    # put all JSPs 
    echo "<br><h3>Referenced JSPs</h3>">> index.html 
    while read aLine; do 
     echo "- $aLine<br>" >> index.html 
    done < jsp.cwl 
    # put all JSs 
    echo "<br><h3>Referenced JavaScript</h3>">> index.html 
    while read aLine; do 
     echo "- $aLine<br>" >> index.html 
    done < js.cwl 
    # put all htms 
    echo "<br><h3>Referenced htm</h3>">> index.html 
    while read aLine; do 
     echo "- $aLine<br>" >> index.html 
    done < htm.cwl 
    # put all css 
    echo "<br><h3>Referenced css</h3>">> index.html 
    while read aLine; do 
     echo "- $aLine<br>" >> index.html 
    done < css.cwl 
    echo "</body></html>" >> index.html 

    # generate a html for each class file and put all accessed methods in it 
    for aLine in $(ls *.cwl); do 
     cat $aLine | uniq > tmp; mv tmp $aLine 
     fileName=$(echo $aLine | sed 's/\.cwl//g') 
     echo "#G# generating $fileName.html" 
     echo "<html><body bgcolor=\"#ffddee\">" >> $fileName.html 
     echo "<h3>$fileName</h3>" >> $fileName.html 
     for bLine in $(cat $aLine | sort); do 
      echo "$bLine<br>" >> $fileName.html 
     done 
     echo "</body></html>" >> $fileName.html 
    done 

    # cleanup and return 
    #rm *.cwl *tmp* 
    cd .. 

done 

echo "</body></html>" >> ./dir.html 
rm ../allFiles$2 
echo "### CodeCrawler finished" 
+0

이 스크립트는 무엇입니까? – OscarRyz

+0

파일 세트에서 모든 Java 클래스/JSP 참조를 생성하려고 시도합니다. – Amarsh

4

왜 중단 점이 도움이되지 않습니까? 디버거로 코드를 밟아야합니다. 코드가 스파게티인지 여부는 시스템의 "디버그 기능"에 영향을주지 않습니다.

이 난장판을 다루는 방법에 대해서는 기존 시스템에 대한 단위 테스트 톤을 작성하는 것이 좋습니다. 그것은 당신이 프로그램을 더 잘 이해할 수있게 해주 며, 리팩토링이 필요할 때마다 더 나은 상황에 처하게 할 것입니다. 살펴 보시길 http://amzn.com/0131177052

+0

하나의 커다란 몰로치라면 테스트 할 수있는 유닛을 찾기가 어려울 수 있습니다. – tangens

+0

확실히! 그것이 그 책이 도움이되는 곳입니다. 오래되고 크고 못생긴 코드베이스를 다룰 때. – cherouvim

+0

중단 점은 대부분의 메서드 호출 스택이 매우 깊기 때문에 도움이되지 않습니다. jsps와 javascript의 비즈니스 로직이 어려움을 더합니다. 어떤 방법으로 스택 추적을 할 수 있는지 궁금 해서요 (코드가 잘 작성된 경우 log.trace 문을 보는 것보다 훨씬 낫지 만), 시퀀스가 ​​무엇인지 알기 위해 건너 뛸 수 있습니다. 프로파일 러는 호출 된 모든 메소드 목록을 생성하지만 특정 순서는 생성하지 않습니다. – Amarsh

3

코드를 편집 할 수 있다면 좋은 방법이 도움이 될 수 있습니다 : System.err.println()을 전략 지점에 두십시오. 이 프로그램은 프로그램의 흐름을 보여줍니다. 이는 아마도 알려지지 않은 코드를 발견하는 첫 번째 단계 일 것입니다.

추적에서 일부 변수 값 또는 스택 추적도 표시 할 수 있습니다 (new Exception().printStackTrace(System.err) 사용). 메시지가 넘치지 않게하려면, 가치가있는 경우에만 println을 실행하는 사전 조건으로 추적을 지켜야합니다.

각 메시지에 참조 할 현재 클래스와 메서드를 넣어야합니다. 메시지에 코드 println의 위치가 명확하게 표시되며 완료되면 모든 추적을 제거하는 데 많은 도움이됩니다.

2

당신이 도구를 사용하여 Java 코드의 실행을 추적하려면

InTrace을했다.