在簡(jiǎn)書上新開博客贿条,趁著熱乎勁处窥,寫篇工作心得過過癮扮念。
這個(gè)最佳實(shí)踐來自于一個(gè)defect。準(zhǔn)確說是BPM的一些不足帶來的一些不方便trouble shooting的問題碧库,加上隨意的流程設(shè)計(jì)柜与,造成了出錯(cuò)的地方和問題暴露的地方相差十萬八千里,甚至開始時(shí)很難把這兩個(gè)問題聯(lián)想到一起嵌灰。
錯(cuò)誤的Log像這樣:
[4/28/16 20:52:47:304 CEST] 0002f2c7 wle? ? ? ? ? E? CWLLG0326E: The BPD encountered an error.
com.lombardisoftware.core.TeamWorksException: java.lang.Object
at com.lombardisoftware.core.TeamWorksException.asTeamWorksException(TeamWorksException.java:136)
at com.lombardisoftware.client.persistence.common.DAOHelper.serializeObject(DAOHelper.java:166)
at com.lombardisoftware.client.persistence.common.DAOHelper.serializeAndCompressIfNeeded(DAOHelper.java:140)
at com.lombardisoftware.bpd.runtime.engine.BPDInstanceDAO.updateExecutionContext(BPDInstanceDAO.java:416)
at com.lombardisoftware.bpd.runtime.engine.BPDInstanceDAO.save(BPDInstanceDAO.java:338)
[4/28/16 20:52:47:390 CEST] 0002f2c7 wle_scheduler E?? CWLLG0181E: The following error occurred in the 5,374,817 task: Not a valid char constructor input: in_creation
com.lombardisoftware.core.TeamWorksException: Not a valid char constructor input: in_creation
at com.lombardisoftware.core.TeamWorksException.asTeamWorksException(TeamWorksException.java:136)
at com.lombardisoftware.bpd.runtime.engine.quartz.AbstractBpdTask.execute(AbstractBpdTask.java:137)
at com.lombardisoftware.bpd.runtime.engine.quartz.AbstractBpdTask.execute(AbstractBpdTask.java:55)
at com.lombardisoftware.server.scheduler.Engine.execute(Engine.java:918)
錯(cuò)誤的原因看著很簡(jiǎn)單弄匕,串行化失敗。當(dāng)時(shí)結(jié)合日志上下文沽瞭,錯(cuò)誤地點(diǎn)定位在非本人維護(hù)的activity當(dāng)中迁匠,想當(dāng)然的就transfer出去了。
問題又很快被踢回來了,原因是錯(cuò)誤也沒有在他們的activity當(dāng)中城丧。兩個(gè)activity之間出錯(cuò)延曙,那90%是傳遞的參數(shù)問題。兩個(gè)activity雖然傳遞的參數(shù)不多亡哄,但要debug還挺花時(shí)間枝缔,費(fèi)了番功夫之后,神奇的事情出現(xiàn)了蚊惯。所有參數(shù)直接顯式賦值確保沒有串行化問題之后還是報(bào)錯(cuò)愿卸。帶著絕望的心情,我又費(fèi)了更大的功夫(媽媽說有5x個(gè)截型,賦值邏輯分散在各個(gè)activities里面趴荸,調(diào)試還沒有整套環(huán)境T_T)把所有BPD中間定義的所有參數(shù)全部隱去,錯(cuò)誤消失了宦焦!
后面事情就簡(jiǎn)單了发钝,過濾/定位后發(fā)現(xiàn)原來是新人加的一個(gè)Any類型的參數(shù),參數(shù)的初始化賦值是轉(zhuǎn)化自一個(gè)javascript的JSON object波闹,并用Java的map重構(gòu)酝豪。但沒有考慮multi-layer,把一個(gè)javascript JSON object賦值到了java的object里面舔痪。修改邏輯后問題解決。
重新來看這個(gè)問題锌唾,為什么這個(gè)參數(shù)為什么之前一直沒有暴露問題锄码,而單單到其它activity,還且還是沒有任何調(diào)用操作的activity出錯(cuò)了晌涕?現(xiàn)在事后想想滋捶,首先報(bào)錯(cuò)的activity是一個(gè)existing的BPD,而不是當(dāng)前BPD下面定義的一個(gè)activity余黎。當(dāng)流程從當(dāng)前BPD轉(zhuǎn)到報(bào)錯(cuò)的activity時(shí)重窟,BPM的內(nèi)在邏輯看來把所有原BPD中的參數(shù)都串行化并持久存儲(chǔ)起來,然后切換上下文環(huán)境來跑下一個(gè)由existing BPD生成的activity惧财。但由于初始化的錯(cuò)誤巡扇,串行化失敗,無法持久化垮衷,報(bào)錯(cuò)了厅翔。
這個(gè)問題總共花了4天時(shí)間debug,中間情節(jié)曲折搀突,問題定位艱難刀闷,一個(gè)是我自身對(duì)BPM不熟,第二是當(dāng)時(shí)候BPD設(shè)計(jì)過分依賴Any參數(shù)。Any參數(shù)忽略的類型檢驗(yàn)甸昏,雖然易于編程顽分,但調(diào)試卻困難重重。所以不是萬不得已施蜜,不建議在BPD中使用Any類型的參數(shù)卒蘸。