項目開發bug記錄

  項目開發中遇到了一個問題,類中出現未知屬性 ‘ $jacocoData ’,準確的來講,實際上在集成測試階段,系統自動運行測試用例時,拋出來的異常提示信息,可是在開發階段是不存在的。這個問題是之前沒有遇到過的一中bug,所以在此處記錄並分析。java

 

 (與本片無關,介意者忽略)框架

  先在這兒介紹一下目前項目的開發模式,使用的是迭代式開發。(參考百度)jvm

  1.瀑布式開發: 瀑布模型式是最典型的預見性的方法,嚴格遵循預先計劃的需求、分析、設計、編碼、代碼審閱、測試、維護的步驟順序進行。maven

            適用:系統目標需求明確,時間固定,函數

  2.敏捷式開發:敏捷開發以用戶的需求進化爲核心,採用迭代、按部就班的方法進行軟件開發。敏捷式開發是一種開發方法。工具

           適用:以用戶爲導性,快速開發,驗證,修正的一種開發方式。單元測試

  3. 迭代式開發:在迭代開發中,整個開發工做被組織爲一系列的短小的、固定長度(如3周)的小項目,被稱爲一系列的迭代,這叫迭代開發。測試

                 每一次迭代都包括了定義、需求分析、設計、實現與測試。迭代式開發是一種開發過程。編碼

         適用:需求不明確,持續進行變動的項目,能夠下降風險,提升複用性。spa

 

  目前fn先生所開發項目的相關步驟:

    1. 任務需求:由PD產出需求,分析以後,明確本次迭代的checkList;

    2. 文檔編寫:由開發/測試共同編寫,其中需求背景,開發思路,系統交互,接口文檔,測試場景,上線時間,人員排期及FAQ等;

    3. 項目階段:開發階段 -> 集成測試 -> 預發灰度 ->項目上線;

      注:在開發完成時,須要有交付報告產出,代表本次開發的影響點,風險點,上線時間,jar發佈版本,系統間交互影響,是否可回滾等等;

    4. 下個需求:哎,惆悵,輪番轟炸吶!!!頭髮都快成C字型了。

 

 (正文)

  如題,所遇到的狀況是:

    類說明:繼承多層級的抽象類,其下有多個子類,其中有一type屬性對應該類的類型,還有一個屬性properties對應不一樣的數據類型,及自定義的數據解析動做;

    場景說明:獲取數據集合後,能夠獲得每一個element的type,可是具體的properties的屬性還須要進行再次處理,因此這兒如何拿到每一個element對應的具體類型,就是處理的關鍵。

    

  在處理上述狀況時,想到兩種處理方式

    1. 根據type建立一個Enum類,存儲type對應的class,並初始化一個實例,再進行具體處理;

    2. 根據type利用反射技術,從新建立一個對象,將其賦原始值後,再進行其具體類的指定處理動做;(本文只記錄分析bug,不講解反射)

  

   當時沒有想太多,採用的是第二種方式處理,利用反射(reflect)進行不一樣類的針對性處理。

    1. 遍歷獲取的抽象類的集合信息,得到element;

    2. 判斷其具體type,進行實例化新的對象(newInstance),得到該類,包含其父類全部的屬性(注意此處);

    3. 利用反射進行對新實例對象的賦值( field.set( newInstance,value ) 注意此處),以後進行具體的處理動做,如調用properties的解析函數...等;

 

  上面的步驟在dev環境下,全部執行操做都是OK的,可是在集成測試階段時,測試用例自動執行時,拋出【Method not found : $jacocoData】。

  排查以後,發現是集成測試環境下,經過反射獲取數據時,多出兩個屬性, $jacocoData   ...(呃,那個屬性忘了),這兩個屬性經過反射賦值時,就會拋出如上異常。

 

  可是爲何會出現上面的多餘屬性呢

    由於在集成測試階段,測試用例執行的時候,maven集成了Jacoco來統計單元測試的代碼覆蓋率,而dev環境沒有做相應的配置。

    Jacoco 會利用編譯器在編譯期間加入 $jacocoData 成員變量,Jacoco使用 asm 實現字節碼植入,是對指令級別上的字節碼植入,從而能夠定位到執行的代碼行。

  

  asm是什麼?(CSDN)

    ASM是一個java字節碼操縱框架,它能被用來動態生成類或者加強既有類的功能。ASM 能夠直接產生二進制 class 文件,也能夠在類被加載入 Java 虛擬機以前動態改變類行爲。Java class 被存儲在嚴格格式定義的 .class文件裏,這些類文件擁有足夠的元數據來解析類中的全部元素:類名稱、方法、屬性以及 Java 字節碼(指令)。ASM從類文件中讀入信息後,可以改變類行爲,分析類信息,甚至可以根據用戶要求生成新類。

    ASM是一款操做class文件流的工具類,效率大大高於普通Java代碼編譯成class的方式。操做class流的方式其實就是經過手動操做jvm的指令集,來生成或修改class文件流。衆所周知普通Java代碼經過javac編譯生成class文件後,再經過javap -v 便可查看反編譯的相似彙編代碼。而asm的實現方式就是完成這樣的彙編代碼。

   

  如何解決該問題 ?(CSDN)

    在反射遍歷字段的時候,能夠對字段進行判斷看是不是複合字段,假如是複合字段就跳出,具體函數是:field.isSynthetic() 爲true證實是複合字段,continue;

      注:synthetic總的來講,是由編譯器引入的字段、方法、類或其餘結構,主要用於JVM內部使用,爲了遵循某些規範而做的一些小技巧從而繞過這些規範,有點做弊的感受,只不過是由編譯器光明正大的,人爲是沒有權限的(但事實上有時候仍是能被利用到的)。

  

  -_- 汗~~

  查詢以後,雖然也是隻知其一;不知其二,可是程序運行時,拋的異常是能夠先解決了,從新提交代碼合併...............走你...........................

 

  參考文檔連接:

    https://blog.csdn.net/shawn_ling/article/details/81205705

    https://blog.csdn.net/samyang1/article/details/79853270

    https://blog.csdn.net/kifgep/article/details/82757417

 

 

  (願你的每一行代碼,都有讓世界進步的力量    ------   fn)

相關文章
相關標籤/搜索