[英]java tracing spaghetti code
Folks, I have just joined this company which has a huge source tree based upon JSP/Servlet and EJB 1.2. 伙计们,我刚刚加入这家公司,该公司拥有一个基于JSP / Servlet和EJB 1.2的巨大源代码树。 No documentation exists. 没有文档。 The code has been written over seven years, with a large number of undocumented changes. 该代码已编写了七年之久,其中有大量未记录的更改。 Are there any tool tah can assist me in tracing the execution? 有没有什么工具可以帮助我追踪执行情况? Putting a breakpoint is not helping me much. 设置断点对我没有多大帮助。
Why are breakpoints not helpful? 为什么断点没有帮助? Stepping in the code with the debugger should work. 使用调试器单步执行代码应该可以。 Whether the code is spaghetti or not shouldn't affect the "debugability" of the system. 代码是否为意大利面条不应该影响系统的“可调试性”。
On how to deal with this mess I suggest writing tons of unit tests for the existing system. 关于如何处理这种混乱,我建议为现有系统编写大量的单元测试。 It'll allow you to understand the program better and be in a better situation for refactorings as soon as these are needed (obviously very soon). 它使您可以更好地了解程序,并在需要重构时(显然很快)可以更好地进行重构。 Have a look at http://amzn.com/0131177052 看看http://amzn.com/0131177052
The good old trick can help here if you're allowed to edit the code: put many System.err.println()
at strategic points. 如果允许您编辑代码,那么好的旧技巧可以在这里有所帮助:将许多System.err.println()
放在战略要点。 It shows the flow of the program, which is probably the first step to discover unknown code. 它显示了程序的流程,这可能是发现未知代码的第一步。
The trace can also display some variable values or even a stack trace (use new Exception().printStackTrace(System.err)
). 跟踪还可以显示一些变量值,甚至可以显示堆栈跟踪(使用new Exception().printStackTrace(System.err)
)。 To avoid a flood of messages, the trace can be guarded by a pre-condition that executes the println
only if it worth it. 为了避免消息泛滥,可以通过前提条件来保护跟踪,前提是仅在值得时才执行println
。
Be sure to put in each message the current class and method to reference. 确保在每条消息中放入当前要引用的类和方法。 The message shows clearly the location of the println
code, and it will help a lot to remove all the traces when you're done! 该消息清楚地显示了println
代码的位置,当您完成操作后,将有助于删除所有痕迹!
Great thanks for everyone's inputs. 非常感谢大家的投入。 It was a wonderful learning experience. 这是一次很棒的学习经历。 I ended up writing my shell script, which produces a html report. 我最终写了我的shell脚本,该脚本生成了html报告。 I am attaching the complete file here. 我在这里附上完整的文件。
Please note that I am not a regular shell programmer, and I was working on this after hours .. hence the standard of the code is not too good. 请注意,我不是一名普通的Shell程序员,而且下班后我一直在从事此工作..因此代码的标准不是很好。 It has plenty of cut/past jobs off the internet. 它在互联网上有大量剪切/粘贴工作。 It works however, and presents the approach you may take to go through your sphegatti code. 但是它可以工作,并介绍您可能需要执行的Sphegatti代码的方法。
Regards 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"
如果要跟踪Java代码的执行,可以使用一个名为InTrace的工具。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.